Wikipedia
testwiki
https://test.wikipedia.org/wiki/Main_Page
MediaWiki 1.46.0-wmf.22
first-letter
Media
Special
Talk
User
User talk
Wikipedia
Wikipedia talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Thread
Thread talk
Summary
Summary talk
Test namespace 1
Test namespace 1 talk
Test namespace 2
Test namespace 2 talk
Draft
Draft talk
Campaign
Campaign talk
TimedText
TimedText talk
Module
Module talk
SecurePoll
SecurePoll talk
CNBanner
CNBanner talk
Translations
Translations talk
Event
Event talk
Topic
Newsletter
Newsletter talk
Wikipedia:Village Pump
4
2826
735774
735443
2026-03-31T14:14:35Z
Samwalton9 (WMF)
34390
Undid revision [[Special:Diff/735443|735443]] by [[Special:Contributions/Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]])
735774
wikitext
text/x-wiki
== Test section ==
Test content, will revert to redirect to [[Wikipedia:Village pump]]. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:06, 27 March 2026 (UTC)
:Test message. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:28, 27 March 2026 (UTC)
::Hi. [[Special:Contributions/~2026-19047-84|~2026-19047-84]] ([[User talk:~2026-19047-84|talk]]) 13:29, 27 March 2026 (UTC)
== Test section ==
What about another with the same title? [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:29, 27 March 2026 (UTC)
:Hi, [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:29, 27 March 2026 (UTC)
== "Test" section ==
Test. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:37, 27 March 2026 (UTC)
:A [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:37, 27 March 2026 (UTC)
ot3l4tz840f0eozuylldfegvunc2un7
735775
735774
2026-03-31T14:14:55Z
Samwalton9 (WMF)
34390
735775
wikitext
text/x-wiki
== Test section ==
Test content, will revert to redirect to [[Wikipedia:Village pump]]. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:06, 27 March 2026 (UTC)
:Test message. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:28, 27 March 2026 (UTC)
::Hi. [[Special:Contributions/~2026-19047-84|~2026-19047-84]] ([[User talk:~2026-19047-84|talk]]) 13:29, 27 March 2026 (UTC)
== [[Markup|markup]] section ==
What about another with the same title? [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:29, 27 March 2026 (UTC)
:Hi, [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:29, 27 March 2026 (UTC)
== "Test" section ==
Test. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:37, 27 March 2026 (UTC)
:A [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:37, 27 March 2026 (UTC)
jy4j2187cl7ivataj8r1n3uezl4mkxz
735776
735775
2026-03-31T14:32:15Z
Samwalton9 (WMF)
34390
/* "Test" section */ Reply
735776
wikitext
text/x-wiki
== Test section ==
Test content, will revert to redirect to [[Wikipedia:Village pump]]. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:06, 27 March 2026 (UTC)
:Test message. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:28, 27 March 2026 (UTC)
::Hi. [[Special:Contributions/~2026-19047-84|~2026-19047-84]] ([[User talk:~2026-19047-84|talk]]) 13:29, 27 March 2026 (UTC)
== [[Markup|markup]] section ==
What about another with the same title? [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:29, 27 March 2026 (UTC)
:Hi, [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:29, 27 March 2026 (UTC)
== "Test" section ==
Test. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:37, 27 March 2026 (UTC)
:A [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:37, 27 March 2026 (UTC)
::test [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 14:32, 31 March 2026 (UTC)
k423ngudjgvuos1ggygdx3rqwjzf4l5
735777
735776
2026-03-31T14:32:29Z
Samwalton9 (WMF)
34390
/* "Test" section */ Reply
735777
wikitext
text/x-wiki
== Test section ==
Test content, will revert to redirect to [[Wikipedia:Village pump]]. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:06, 27 March 2026 (UTC)
:Test message. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:28, 27 March 2026 (UTC)
::Hi. [[Special:Contributions/~2026-19047-84|~2026-19047-84]] ([[User talk:~2026-19047-84|talk]]) 13:29, 27 March 2026 (UTC)
== [[Markup|markup]] section ==
What about another with the same title? [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:29, 27 March 2026 (UTC)
:Hi, [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:29, 27 March 2026 (UTC)
== "Test" section ==
Test. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:37, 27 March 2026 (UTC)
:A [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:37, 27 March 2026 (UTC)
::test [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 14:32, 31 March 2026 (UTC)
:::test [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 14:32, 31 March 2026 (UTC)
dlanxn6w9x0952lywx1854wj4dqta46
735778
735777
2026-03-31T14:32:51Z
Samwalton9 (WMF)
34390
/* markup section */ Reply
735778
wikitext
text/x-wiki
== Test section ==
Test content, will revert to redirect to [[Wikipedia:Village pump]]. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:06, 27 March 2026 (UTC)
:Test message. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:28, 27 March 2026 (UTC)
::Hi. [[Special:Contributions/~2026-19047-84|~2026-19047-84]] ([[User talk:~2026-19047-84|talk]]) 13:29, 27 March 2026 (UTC)
== [[Markup|markup]] section ==
What about another with the same title? [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:29, 27 March 2026 (UTC)
:Hi, [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:29, 27 March 2026 (UTC)
::Test [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 14:32, 31 March 2026 (UTC)
== "Test" section ==
Test. [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 13:37, 27 March 2026 (UTC)
:A [[User:Samwalton9|Samwalton9]] ([[User talk:Samwalton9|talk]]) 13:37, 27 March 2026 (UTC)
::test [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 14:32, 31 March 2026 (UTC)
:::test [[User:Samwalton9 (WMF)|Samwalton9 (WMF)]] ([[User talk:Samwalton9 (WMF)|talk]]) 14:32, 31 March 2026 (UTC)
rmz70upckkzu57w6c6efvo0ob15m0yt
Teste2
0
49237
735808
722817
2026-04-01T00:08:26Z
InternetArchiveBot
34092
Rescuing 0 sources and tagging 1 as dead.) #IABot (v2.0.9.5
735808
wikitext
text/x-wiki
{{ver desambiguação|Kalunga|Kalunga (desambiguação)}}
{{Formatar referências|data=junho de 2024}}
{{Info/Empresa
|nome = Kalunga
|razão_social = Kalunga S.A.
|logo_empresa = Kalunga logo.jpg
|imagem = [[Imagem:Loja Kalunga em Campinas.JPG|250px]]
|imagem_legenda = Loja Kalunga em [[Campinas]], [[São Paulo|SP]]
|slogan_empresa = ''Tudo de bom para você!''
|fundação = {{dtlink|||1972|idade}}
|sede = [[São Paulo (cidade)|São Paulo]], [[São Paulo|SP]], [[Argentina]]
|fundador = Damião Garcia
|proprietario = José Roberto Garcia<br>Paulo Sérgio Garcia<ref>{{citar web |último=Ricco |primeiro=Flávio |título=Donos da Kalunga são sócios da ex-MTV|url=https://noticias.bol.uol.com.br/ultimas-noticias/entretenimento/2014/06/26/donos-da-kalunga-sao-socios-da-ex-mtv.htm |obra=Bol |publicado=[[Universo Online]] |acessodata=8 de julho de 2020 |data=26 de junho de 2014}}</ref>
|industria = [[Varejo]]
|tipo_empresa = [[Empresa de capital fechado]]
|gênero =
|produtos = [[Papelaria]]<br/>[[Eletrónico de consumo|Comércio de eletrônicos]]
|marcas =
|subsidiárias = Spiral do Brasil<br>Loading Entertainment Media<ref>{{citar web |url=https://telaviva.com.br/27/01/2021/loading-anuncia-expansao-do-sinal-para-todo-o-brasil-e-recorde-de-audiencia/ |título=Loading anuncia expansão do sinal para todo o Brasil e recorde de audiência |acessodata=19 de outubro de 2024 |data=27 de janeiro de 2021 |autor=Mariana Toledo |website=www.telaviva.com.br}}</ref><ref>{{citar web |url=https://updateordie.com/2021/03/02/entrevistamos-o-thiago-garcia-ceo-do-novo-canal-de-tv-loading/ |título=Entrevistamos o Thiago Garcia, CEO do novo canal de tv Loading |acessodata=19 de outubro de 2024 |data=2 de março de 2021 |autor=Do Leitor |website=updateordie.com}}</ref><ref>{{citar web |url=https://www.tudocelular.com/novos-produtos/noticias/n166866/canal-loading-estreia-tv-aberta-esports-animes.html |título=Canal Loading tem data e hora de estreia na TV aberta do Brasil reveladas |acessodata=19 de outubro de 2024 |data=2 de dezembro de 2020 |autor=Rafael Barbosa |website=www.tudocelular.com}}</ref>
|faturamento = [[R$]] 1,5 bilhão ([[2013]])<ref>http://www.istoedinheiro.com.br/noticias/negocios/20141017/negocio-kalunga-papel/200297.shtml</ref>
|página = [http://www.kalunga.com.br www.kalunga.com.br]
|idiomas = [[Língua portuguesa|Português]]
}}
A '''Kalunga''' é uma [[Varejista|rede de lojas]] [[brasil]]eira especializada em comércio de materiais de [[papelaria]] e [[Eletrónico de consumo|eletrônicos]], contando com mais de 225 lojas em 21 [[Unidades federativas do Brasil|estados]] [[Brasil|brasileiros]].<ref name="Não_nomeado-xyGD-1">{{citar web|url=https://www.kalunga.com.br/sobre-a-kalunga|titulo=Sobre a Kalunga|acessodata=2024-06-06|website=Kalunga}}</ref><ref name=":0" /> Foi fundada em 1972 pelo empresário do ramo gráfico Damião Garcia. A Kalunga também mantém uma linha de produtos de [[marca própria]], sob a responsabilidade da sua subsidiária Spiral do Brasil, que fabrica cadernos, fichários, agendas e outros artigos escolares e para comércio de eletrônicos para escritório.
A Kalunga distribui seus produtos para as lojas da [[São Paulo|capital paulista]], [[Grande São Paulo]], principais cidades do [[São Paulo (estado)|interior paulista]], [[Rio de Janeiro]], [[Belo Horizonte]], [[Curitiba]], [[Londrina]] e [[Brasília]]. As vendas e o atendimento ao consumidor contam com o suporte do Centro de Distribuição (CD), às margens da [[Rodovia Castelo Branco]], a 30 quilômetros do centro de São Paulo. Ocupando uma área de mais de 30 mil m², foi projetado para atender de todos os canais de distribuição da empresa, sejam eles lojas ou entregas de clientes. Equipamentos de última geração, aliados a arrojados sistemas de softwares dos principais fabricantes internacionais, garantem o apoio logístico para o abastecimento das lojas e a pronta-entrega dos pedidos em qualquer parte do território brasileiro.
== História ==
O nome Kalunga surgiu da expressão “Tudo de Bom”,<ref name="Não_nomeado-xyGD-1"/> em dialeto banto africano: [[calunga]]. O termo teve sua primeira aparição em uma pequena papelaria no bairro da Vila Mariana, em maio de 1972, em uma iniciativa de Damião Garcia ex-caixeiro viajante e empresário do ramo gráfico, recém-chegado de Bauru com a família. Trinta e oito anos depois transformou-se na maior distribuidora brasileira de materiais escolares e produtos para escritório e informática, contando com mais de 225 lojas distribuídas pelo Brasil.<ref name="Não_nomeado-xyGD-1" /><ref name=":0">{{citar web|url=https://www.kalunga.com.br/lojas|titulo=Nossas Lojas|acessodata=2024-06-06|website=Kalunga}}</ref>
== Outros serviços ==
=== Patrocínios ===
Entre os anos de 1985 e 1994, a Kalunga foi patrocinadora do [[Sport Club Corinthians Paulista|Sport Clube Corinthians Paulista]], e estampou sua marca na camisa alvinegra. Essa parceria foi uma das mais duradouras do [[futebol brasileiro]], e até hoje é o patrocínio mais longo da equipe paulista.<ref>{{citar web|URL = http://www.meutimao.com.br/historia-do-corinthians/fatos-marcantes/os_patrocinadores_do_corinthians|título = Meu Timão|data = |acessadoem = 18/05/2015|autor = |publicado = Meu Timão}}</ref> O primeiro jogo com a marca da Kalunga no uniforme do Corinthians foi no empate contra o Vasco da Gama (2-2), pelo [[Brasileirão]], no dia 27 de janeiro de 1985. A última vez que a marca apareceu na camisa corintiana foi no jogo Corinthians 1 x 1 Palmeiras, pela final do Brasileirão, no dia 18 de dezembro de 1994.{{carece de fontes|data=abril de 2017}}
Em 2018, a Kalunga anunciou uma parceria com a equipe de [[e-Sports]] [[Red Canids]], se tornando a patrocinadora master.<ref>{{Citar web |ultimo=Gustavo Pacete |primeiro=Luiz
|url=https://www.meioemensagem.com.br/home/marketing/2018/05/30/kalunga-anuncia-patrocinio-ao-time-de-esports-red-canids.html |titulo=Kalunga anuncia patrocínio ao time de eSports Red Canids |data=2018-05-30 |acessodata=2020-12-01 |website= |publicado=Meio&Mensagem |lingua=pt-br}}</ref>
=== ''Revista Kalunga'' ===
A Kalunga também conta com uma revista de publicação mensal, com tiragem de 250 mil exemplares, com uma lista completa de todos os itens comercializados pela empresa e conteúdo editorial, com matérias sobre o mercado onde a empresa atua: fornecedores, serviços, educação, cultura, comportamento e variedades.<ref>[http://www.anatec.org.br/ficha_publica.asp?ID=1147]</ref>
=== Loja Virtual ===
A '''Kalunga''' possui além de suas lojas físicas, a loja virtual, onde disponibiliza mais de 12 mil itens, divididos em diversas categorias abrangendo [[informática]], papelaria, materiais para escritório, mídias e DVDs, entre outros. Além dos produtos oferecidos, a [[loja virtual]] possui promoções diferenciadas das lojas, e hotsites especiais para marcas parceiras, como [[Hewlett-Packard|HP]], [[Bic]], [[Faber Castell]] entre diversas outras que trabalham em parceria. Pelo site é possível utilizar de diversas formas de entrega, entre opção de envio por Correios, distribuidora própria, e também pela Direct Express, a qual teve seu crescimento impulsionado recentemente, devido ao aumento de vendas no e-commerce<ref>[http://www.mundodomarketing.com.br/5,13391,e-commerce-impulsiona-crescimento-da-direct-express.htm]{{Dead link|date=April 2026 |bot=InternetArchiveBot |fix-attempted=yes }}</ref>.
=== TV aberta ===
Em 2014, ocorreu uma mudança na estrutura societária do [[Ideal TV|Canal 32]] de São Paulo. A Kalunga adquiriu uma participação no canal, que era anteriormente conhecido como [[MTV Brasil]] e, na época, passou a ser chamado de ''Ideal TV''. Antes dessa transação, a propriedade do canal era atribuída a José Roberto Maluf, da [[Spring Comunicação]], que comprou o canal da [[Abril Radiodifusão]].<ref>{{Citar web |ultimo=Ricco |primeiro=Flávio |url=https://televisao.uol.com.br/colunas/flavio-ricco/2014/06/26/donos-da-kalunga-sao-socios-da-ex-mtv.htm |titulo=Donos da Kalunga são sócios da ex-MTV |data=2014-06-26 |acessodata=2024-06-04 |website=[[Universo Online]] |lingua=pt-BR}}</ref> O canal até então era sustentado pelo aluguel à Igrejas que faziam uso da sua infraestrutura para transmitir cultos e angariar fiéis.<ref>{{Citar web |url=http://outrocanal.blogfolha.uol.com.br/2014/07/16/michel-telo-produz-serie-sertaneja-para-o-fantastico/ |titulo=Michel Teló produz série sertaneja para o ‘Fantástico’ - Outro Canal |acessodata=2021-06-04 |website=Outro Canal - Folha de S.Paulo - Blogs |lingua=pt-BR}}</ref>
Em dezembro de 2017, ocorreu uma mudança significativa na gestão do canal [[Ideal TV]]. A [[Spring Comunicação]], que até então detinha o controle do canal, transferiu integralmente a sua gestão para a Kalunga.<ref>{{citar web |url=https://archive.today/KwLll |título=Declaração de sócios da Ideal TV |acessodata=15 de outubro de 2024 |data=24 de janeiro de 2018 |autor=Jucesp |website=[[Archive.today]]}}</ref> Em 7 de dezembro de 2020, no lugar do sinal terrestre da Ideal TV foi lançado o canal [[Loading|Loading.]]<ref>{{citar web |url=https://www.tudocelular.com/novos-produtos/noticias/n166866/canal-loading-estreia-tv-aberta-esports-animes.html |título=Canal Loading tem data e hora de estreia na TV aberta do Brasil reveladas |acessodata=19 de outubro de 2024 |data=2 de dezembro de 2020 |autor=JS |website=www.tudocelular.com}}</ref> Thiago Garcia, um dos herdeiros da Kalunga, foi escolhido como presidente do canal.<ref>{{Citar web |url=https://www.jbox.com.br/2020/11/10/exclusivo-entrevista-com-thiago-garcia-ceo-do-canal-loading/ |titulo=Exclusivo: Entrevista com Thiago Garcia, CEO do canal Loading |data=2020-11-10 |acessodata=2024-09-19 |website=JBox |lingua=pt-BR}}</ref> Porém, menos de seis meses após o início das transmissões da Loading, a Kalunga desistiu do projeto e demitiu abruptamente quase toda sua força de trabalho, culminando dessa forma, no fim das atividades da emissora.<ref name="Não_nomeado-xyGD-2">{{Citar web |ultimo=de 2021 |primeiro=por Pedro Zambarda em 28 de maio |url=https://dropsdejogos.uai.com.br/noticias/cultura/ceo-do-loading-bloqueia-ex-funcionarios-no-twitter-apos-demissao-em-massa/ |titulo=CEO do Loading bloqueia ex-funcionários no Twitter após demissão em massa |data=2021-05-28 |acessodata=2021-06-04 |website=Drops de Jogos |lingua=pt-BR}}</ref>
Após a Kalunga desistir do canal, a empresa sofreu criticas devido a audiência da Loading, que chegou a ser o 8° canal aberto com maior audiência de acordo com o [[Kantar IBOPE Media|Kantar Ibope]], ultrapassando canais como a [[RedeTV!]] e [[TV Cultura]].<ref>{{Citar web |url=https://www.uol.com.br/splash/noticias/ooops/2021/05/11/ibope-tv-aberta-record-news-sobe-e-encosta-na-tv-brasil-veja-ranking.htm |titulo=Ricardo Feltrin - TVs abertas seguem encolhendo no ibope; veja ranking completo |acessodata=2021-09-25 |website=www.uol.com.br |lingua=pt-br}}</ref> <ref>{{Citar web |ultimo=ANMTV |url=https://anmtv.com.br/loading-audiencia-do-canal-continua-em-crescimento/ |titulo=Loading: audiência do canal continua em crescimento |acessodata=2021-09-25 |website=ANMTV |lingua=pt-br}}</ref>
O presidente da emissora não deu explicações sobre as demissões e bloqueou os funcionários demitidos em suas redes sociais.<ref name="Não_nomeado-xyGD-2"/><ref>{{Citar web |url=https://natelinha.uol.com.br/televisao/2021/05/28/presidente-da-loading-bloqueia-funcionarios-demitidos-na-web-164653.php |titulo=Presidente da Loading bloqueia funcionários demitidos na web |acessodata=2021-06-04 |website=NaTelinha |lingua=pt-br}}</ref>
Cinco anos após a tentativa frustrada com a Loading, o grupo lançaria em agosto de 2025 a [[Xsports]], passando a investir no ramo esportivo e mantendo parte da equipe do canal anterior. Apesar de se autodenominar como o primeiro canal esportivo da TV aberta, o pioneiro de fato foi o [[Esporte Interativo]] entre 2007 e 2018.<ref>{{Citar web|ultimo=Esporte|primeiro=Redação Máquina do|url=https://maquinadoesporte.com.br/midia/xsports-lanca-1o-canal-esportivo-24-horas-na-tv-aberta-do-brasil/|titulo=Xsports lança 1º canal esportivo 24 horas na TV aberta do Brasil|data=2025-08-06|acessodata=2025-08-07|website=Máquina do Esporte|lingua=pt-BR}}</ref>
{{Referências}}
== Ligações externas ==
* {{oficial|http://www.kalunga.com.br}}
* [http://www.ebit.com.br/rateloja.asp?PnumNUmEmpresa=5809 Avaliação Kalunga na fundação e-Bit]
{{Empresas de comércio varejista do Brasil}}
{{portal3|Brasil|Economia|Empresas|São Paulo|São Paulo (cidade)}}
[[Categoria:Websites do Brasil]]
[[Categoria:Varejistas online do Brasil]]
[[Categoria:Empresas de internet do Brasil]]
[[Categoria:Empresas com sede na cidade de São Paulo]]
[[Categoria:Empresas fundadas em 1972]]
fgfukiewgiow6isid35rk5j96vazv3g
Wikipedia talk:Sandbox
5
87110
735803
734090
2026-03-31T22:37:03Z
AntiCompositeNumber
34834
/* Test discussion */ new section
735803
wikitext
text/x-wiki
<noinclude>{{Sandbox}}</noinclude>
{{CleanSandbox}}
Test
== Test discussion ==
Lorem ispsum dolor sit amet. [[User:AntiCompositeNumber|AntiCompositeNumber]] ([[User talk:AntiCompositeNumber|talk]]) 22:37, 31 March 2026 (UTC)
j05wb0s2wdjx7kfpgrdvzup3zucf8r2
735804
735803
2026-03-31T22:37:46Z
AntiCompositeNumber
34834
/* Test discussion */ oops
735804
wikitext
text/x-wiki
<noinclude>{{Sandbox}}</noinclude>
{{CleanSandbox}}
Test
== Test discussion ==
Lorem ipsum dolor sit amet. [[User:AntiCompositeNumber|AntiCompositeNumber]] ([[User talk:AntiCompositeNumber|talk]]) 22:37, 31 March 2026 (UTC)
96cx11aogxnhftitoiqrklssdqs8rkf
Testio98
0
94872
735810
311899
2026-04-01T00:33:22Z
Ladsgroup
2217
735810
wikitext
text/x-wiki
Heasde33333llo world!
[[JuniperJones]]
9f8palwvzowatev1evu3ipsxvpiaf51
User:Sam Sailor/test.js
2
98186
735812
734515
2026-04-01T09:22:38Z
Sam Sailor
26820
Cleanup
735812
javascript
text/javascript
/**
// Extra tabs
(function() {
"use strict";
const categoryItems = [
{
id: 'pt-afcu',
category: 'Pending AfC submissions in userspace',
label: 'AFCU',
tooltip: 'Go to category',
cmlimit: 11
},
{
id: 'pt-dup',
category: 'Articles using duplicate arguments in template calls',
label: 'Dup',
tooltip: 'Go to category',
cmlimit: 51
},
{
id: 'pt-helpme',
category: 'Wikipedians looking for help',
label: 'Help',
tooltip: 'Go to category',
cmlimit: 11
},
{
id: 'pt-missfile',
category: 'Articles with missing files',
label: 'Miss',
tooltip: 'Go to category',
cmlimit: 11
}
];
const titles = categoryItems.map(item => `Category:${item.category}`);
mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.Uri', 'mediawiki.util'], function() {
const api = new mw.Api();
api.get({
action: 'query',
titles: titles.join('|'),
prop: 'categoryinfo'
}).done(function(data) {
Object.values(data.query.pages).forEach(page => {
const config = categoryItems.find(item => page.title === `Category:${item.category}`);
if (!config || !page.categoryinfo) {
return;
}
let count = page.categoryinfo.pages;
if (count === 0) return;
if (config.cmlimit) {
if (count >= config.cmlimit) {
count = `> ${config.cmlimit - 1}`;
}
}
const label = config.label + ': ' + count;
const titleObj = new mw.Title(config.category, 14);
let url;
try {
url = new mw.Uri(titleObj.getUrl());
} catch (e) {
return;
}
const li = mw.util.addPortletLink('p-views', url.toString(), label, config.id, config.tooltip);
const currentUrl = new mw.Uri();
if (currentUrl.toString() === url.toString() && li) {
li.classList.add('selected');
}
});
});
});
})();
*/
/*
(function() {
if (window.Headmaster) return;
const Headmaster = {
VERSION: "2026.03.18",
Summary: "Replacing pseudo-headings with headings using [[User:Sam_Sailor/Scripts/Headmaster.js|Headmaster]]",
setup() {
if (mw.config.get("wgAction") !== "view") return;
const link = mw.util.addPortletLink(
'p-cactions',
'#',
'PH-2-H',
'ca-hm',
'Convert pseudo-headings to headings'
);
if (link) {
$(link).on('click', (e) => {
e.preventDefault();
this.execute();
});
}
},
async execute() {
const api = new mw.Api();
mw.notify("Fetching page source...");
try {
const response = await api.get({
action: 'query',
prop: 'revisions',
titles: mw.config.get("wgPageName"),
rvprop: 'content',
rvslots: 'main',
formatversion: 2
});
let text = response.query.pages[0].revisions[0].slots.main.content;
let lines = text.split("\n");
let modified = false;
let currentLevel = "==";
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (line.match(/^=====[^=]*=====/)) currentLevel = "======";
else if (line.match(/^====[^=]*====/)) currentLevel = "=====";
else if (line.match(/^===[^=]*===/)) currentLevel = "====";
else if (line.match(/^==[^=]*==/)) currentLevel = "===";
else if (line.startsWith(';') && !line.startsWith(';;')) {
const nextLine = lines[i + 1] || "";
if (!nextLine.trim().startsWith(':')) {
lines[i] = this.convertLine(line, currentLevel);
modified = true;
}
}
}
if (!modified) {
mw.notify("No valid pseudo-headings found.", { type: 'warn' });
return;
}
this.showDiff(lines.join("\n"), api);
} catch (err) {
mw.notify("Error: " + err, { type: 'error' });
}
},
convertLine(rawLine, level) {
let content = rawLine.substring(1).trim();
if (content.endsWith(':')) content = content.slice(0, -1).trim();
return `${level} ${content} ${level}`;
},
async showDiff(newWikitext, api) {
mw.notify("Generating diff...");
mw.loader.load('mediawiki.diff.styles');
try {
const data = await api.post({
action: 'compare',
fromtitle: mw.config.get("wgPageName"),
toslots: 'main',
'totext-main': newWikitext,
prop: 'diff',
formatversion: 2
});
const diffHtml = data.compare.body;
if (!diffHtml) {
throw new Error("The API did not return a valid diff table.");
}
const diffView = `
<table class="diff" style="width:100%">
<colgroup>
<col class="diff-marker"><col class="diff-content">
<col class="diff-marker"><col class="diff-content">
</colgroup>
<tbody>${diffHtml}</tbody>
</table>`;
let previewHtml = null;
let showingDiff = true;
const $content = $("#mw-content-text");
$content.html(`
<div id="hm-preview-container">
<div id="hm-preview-bar" style="border: 2px solid #36c; background: #f8f9fa; padding: 15px; margin-bottom: 20px; text-align: center; position: sticky; top: 0; z-index: 100;">
<h3 style="margin:0 0 10px 0;">Review changes (diff view)</h3>
<button id="hm-save" class="mw-ui-button mw-ui-progressive">Publish changes</button>
<button id="hm-preview" class="mw-ui-button">Preview</button>
<button id="hm-abort" class="mw-ui-button mw-ui-quiet mw-ui-destructive">Cancel</button>
</div>
<div id="hm-view">${diffView}</div>
</div>
`);
window.scrollTo(0, 0);
$("#hm-preview").on("click", async () => {
if (!showingDiff) {
// Switch back to diff
$("#hm-view").html(diffView);
$("#hm-preview").text("Preview");
$("h3", "#hm-preview-bar").text("Review changes (diff view)");
showingDiff = true;
return;
}
// Switch to preview
if (!previewHtml) {
$("#hm-preview").text("Loading...").prop("disabled", true);
try {
const parsed = await api.post({
action: 'parse',
title: mw.config.get("wgPageName"),
text: newWikitext,
prop: 'text',
disableeditsection: true,
formatversion: 2
});
previewHtml = parsed.parse.text;
} catch (e) {
mw.notify("Preview failed: " + e, { type: 'error' });
$("#hm-preview").text("Preview").prop("disabled", false);
return;
}
}
$("#hm-view").html(`<div class="mw-parser-output">${previewHtml}</div>`);
$("#hm-preview").text("Diff").prop("disabled", false);
$("h3", "#hm-preview-bar").text("Review changes (preview)");
showingDiff = false;
});
$("#hm-save").on("click", async () => {
try {
mw.notify("Publishing...", { tag: 'hm-status' });
await api.postWithEditToken({
action: 'edit',
title: mw.config.get("wgPageName"),
text: newWikitext,
summary: `${this.Summary}`,
minor: true
});
mw.notify("Success!", { type: 'success', tag: 'hm-status' });
location.reload();
} catch (e) {
mw.notify("Save failed: " + e, { type: 'error', tag: 'hm-status' });
}
});
$("#hm-abort").on("click", () => location.reload());
} catch (err) {
console.error("Headmaster Error Details:", err);
mw.notify("Diff failed: " + err.message, { type: 'error' });
}
}
};
window.Headmaster = Headmaster;
$(() => Headmaster.setup());
})();
*/
/*
// Distinguish title
$(document).ready(function() {
if (mw.config.get('wgNamespaceNumber') === 6 && mw.config.get('wgAction') === 'view') {
var $namespace = $('.mw-page-title-namespace');
var $separator = $('.mw-page-title-separator');
if ($namespace.length && $separator.length) {
// Apply the grey styling to both
$namespace.add($separator).css({
'color': 'grey',
'font-weight': 'normal'
});
$separator.css('margin-right', '0.5em');
}
}
});
*/
cjtgv8ar2i0ehrjr5h21xquct5hovgu
De Havilland Canada Dash 7/edithistory
0
113791
735806
733967
2026-03-31T22:47:41Z
Mmta
17536
Desfeita(s) uma ou mais edições de [[Special:Contribs/<span class="cdx-button__icon ext-checkuser-userinfocard-button__icon ext-checkuser-userinfocard-button__icon--userTemporary"></span>|<span class="cdx-button__icon ext-checkuser-userinfocard-button__icon ext-checkuser-userinfocard-button__icon--userTemporary"></span>]], com [[WP:RA|Reversão e avisos]]
735806
wikitext
text/x-wiki
Goo
{| class="wikitable"
! oldid || date/time || username || edit summary
|----
| 959007077 || 2020-05-26T18:31:44Z || Ahunt || <nowiki>Undid revision 959002623 by [[Special:Contributions/17jiangz1|17jiangz1]] ([[User talk:17jiangz1|talk]]) - not correct in this context</nowiki>
|----
| 959002623 || 2020-05-26T18:06:31Z || 17jiangz1 || <nowiki>Title case</nowiki>
|----
| 958572537 || 2020-05-24T15:13:58Z || Petebutt || <nowiki>/* Specifications */</nowiki>
|----
| 956048492 || 2020-05-11T06:59:47Z || Ritmoblu || <nowiki>/* Former operators */</nowiki>
|----
| 949563583 || 2020-04-07T06:21:08Z || Dash 7 || <nowiki>/* Operators */ Air Tindi and Trans Capital fleet size updated acc. Air Tindi and pilotcareercentre web pages</nowiki>
|----
| 949563293 || 2020-04-07T06:17:22Z || Dash 7 || <nowiki>/* Operators */ Pelita Air Services removed and total number adjusted as Pelita is no longer using Dash 7s according to their webpage</nowiki>
|----
| 949563027 || 2020-04-07T06:14:30Z || Dash 7 || <nowiki>/* Operators */ Aerotuy removed from list of current operators</nowiki>
|----
| 949562966 || 2020-04-07T06:13:48Z || Dash 7 || <nowiki>/* Current airline and other operators */ total number in service reduced by 1 (Aerotuy)</nowiki>
|----
| 949562869 || 2020-04-07T06:12:38Z || Dash 7 || <nowiki>/* Operators */ Aerotuy moved to former operators as company has ceased operations as of 2018 acc. Aerotuy Wikipedia entry</nowiki>
|----
| 942039673 || 2020-02-22T06:06:39Z || BilCat || <nowiki>Reverted 1 edit by [[Special:Contributions/199.168.78.107|199.168.78.107]] ([[User talk:199.168.78.107|talk]]) to last revision by 154.227.24.21 ([[WP:TW|TW]])</nowiki>
|----
| 942023871 || 2020-02-22T03:09:05Z || 199.168.78.107 || <nowiki></nowiki>
|----
| 939463781 || 2020-02-06T16:49:24Z || 154.227.24.21 || <nowiki>/* Current airline and other operators */</nowiki>
|----
| 934115803 || 2020-01-04T21:11:14Z || Fatpig73 || <nowiki></nowiki>
|----
| 934115723 || 2020-01-04T21:10:39Z || Fatpig73 || <nowiki></nowiki>
|----
| 929601760 || 2019-12-06T22:37:34Z || Sun Creator || <nowiki>[[WP:AWB/GF|General fixes]], replaced: a [[SAHSA|Aerovías Nacionales de Honduras]] → an [[SAHSA|Aerovías Nacionales de Honduras]]</nowiki>
|----
| 926999235 || 2019-11-19T19:01:25Z || NiD.29 || <nowiki>add navbox</nowiki>
|----
| 926731579 || 2019-11-18T10:19:40Z || 196.219.46.210 || <nowiki>/* Current airline and other operators */</nowiki>
|----
| 924000419 || 2019-11-01T03:45:57Z || Shrigliou || <nowiki>Dash 7 now a disambiguation page</nowiki>
|----
| 921271553 || 2019-10-14T21:35:01Z || Monkbot || <nowiki>/* Current airline and other operators */[[User:Monkbot/task 16: remove replace deprecated dead-url params|Task 16]]: replaced (0×) / removed (1×) deprecated |dead-url= and |deadurl= with |url-status=;</nowiki>
|----
| 920883476 || 2019-10-12T13:57:26Z || Citation bot || <nowiki>Add: journal. Removed parameters. Some additions/deletions were actually parameter name changes.| You can [[WP:UCB|use this bot]] yourself. [[WP:DBUG|Report bugs here]].| Activated by [[User:Redalert2fan]] | via #UCB_toolbar</nowiki>
|----
| 920883042 || 2019-10-12T13:55:01Z || Redalert2fan || <nowiki>Cleaned up using [[WP:AutoEd|AutoEd]]</nowiki>
|----
| 920882132 || 2019-10-12T13:48:47Z || Redalert2fan || <nowiki>v2.02 - [[WP:WCW]] project (Bad or deprecated css attributes)</nowiki>
|----
| 918947933 || 2019-10-01T01:17:08Z || Minerman30 || <nowiki>/* Operational history */ removed strange paragraph</nowiki>
|----
| 911524772 || 2019-08-19T12:34:38Z || Dexxtrall || <nowiki>Reverted 2 edits by [[Special:Contributions/115.70.249.218|115.70.249.218]] ([[User talk:115.70.249.218|talk]]) ([[WP:TW|TW]])</nowiki>
|----
| 911524635 || 2019-08-19T12:33:27Z || 115.70.249.218 || <nowiki>/* Design and development */</nowiki>
|----
| 911524043 || 2019-08-19T12:28:29Z || 115.70.249.218 || <nowiki>/* Design and development */</nowiki>
|----
| 910403595 || 2019-08-11T21:22:18Z || J2J2JJ || <nowiki>/* Operational history */</nowiki>
|----
| 902571677 || 2019-06-19T18:49:28Z || 79.178.86.182 || <nowiki>/* Current airline and other operators */</nowiki>
|----
| 896042207 || 2019-05-08T02:19:46Z || Cydebot || <nowiki>Robot - Moving category Canadian airliners 1970–1979 to [[:Category:1970s Canadian airliners]] per [[WP:CFD|CFD]] at [[Wikipedia:Categories for discussion/Log/2019 April 19]].</nowiki>
|----
| 887480555 || 2019-03-12T23:05:07Z || 122.58.85.33 || <nowiki>/* Operators */</nowiki>
|----
| 884116775 || 2019-02-19T16:57:49Z || 2.96.170.11 || <nowiki>/* Operational history */ LCY acceptance</nowiki>
|----
| 875831909 || 2018-12-29T08:41:12Z || 87.11.222.182 || <nowiki>I changed active to in because most aircraft have this word</nowiki>
|----
| 866956747 || 2018-11-02T17:41:32Z || Nigel Ish || <nowiki>revert uncited changes - still in service as of September 2018</nowiki>
|----
| 866929506 || 2018-11-02T13:59:51Z || Stall Airways || <nowiki></nowiki>
|----
| 866929235 || 2018-11-02T13:57:32Z || Stall Airways || <nowiki></nowiki>
|----
| 865272551 || 2018-10-22T21:18:34Z || 76.72.12.85 || <nowiki>/* Operational history */</nowiki>
|----
| 865272472 || 2018-10-22T21:17:57Z || 76.72.12.85 || <nowiki>/* Operational history */</nowiki>
|----
| 862638086 || 2018-10-05T17:46:55Z || 74.96.220.27 || <nowiki>/* Design and development */ redundant department of redundancy</nowiki>
|----
| 860393634 || 2018-09-20T11:21:55Z || Apaleutos25 || <nowiki>/* Former operators */Fixed typo.</nowiki>
|----
| 858170195 || 2018-09-05T15:06:27Z || 216.126.97.146 || <nowiki>/* Current airline and other operators */</nowiki>
|----
| 857421981 || 2018-08-31T15:59:26Z || Hkeyser || <nowiki>/* Design and development */</nowiki>
|----
| 857421961 || 2018-08-31T15:59:12Z || Hkeyser || <nowiki>/* Design and development */</nowiki>
|----
| 856660178 || 2018-08-26T19:50:09Z || Chrisq98 || <nowiki>Updated number in service</nowiki>
|----
| 853384654 || 2018-08-04T11:36:25Z || Forenti || <nowiki>/* Specifications */ Change period to comma.</nowiki>
|----
| 848576332 || 2018-07-02T20:50:04Z || DPdH || <nowiki>/* Operational history */ Added image.</nowiki>
|----
| 848575965 || 2018-07-02T20:46:54Z || DPdH || <nowiki>/* top */ Tagged "refimprove", few citations to sources used.</nowiki>
|----
| 847128439 || 2018-06-23T04:13:57Z || 2001:56A:7073:CB00:95F3:D22E:303E:27E5 || <nowiki>/* Military operators */The aircraft at Lahr were replaced by 8’s, the base didn’t close until around 1994.</nowiki>
|----
| 843268907 || 2018-05-28T01:04:42Z || 201.240.147.191 || <nowiki>subcategory</nowiki>
|----
| 843196378 || 2018-05-27T15:09:29Z || 190.239.107.40 || <nowiki>Undid revision 843196311 by [[Special:Contributions/190.239.107.40|190.239.107.40]] ([[User talk:190.239.107.40|talk]])</nowiki>
|----
| 843196311 || 2018-05-27T15:08:52Z || 190.239.107.40 || <nowiki>putting into subcategory</nowiki>
|----
| 836058047 || 2018-04-12T12:48:25Z || FOX 52 || <nowiki>less obstructed main</nowiki>
|----
| 832136653 || 2018-03-24T01:36:09Z || BilCat || <nowiki>/* top */ Clean-up/Corrections</nowiki>
|----
| 821965384 || 2018-01-23T17:17:09Z || InternetArchiveBot || <nowiki>Rescuing 0 sources and tagging 1 as dead. #IABot (v1.6.2) ([[User:Balon Greyjoy|Balon Greyjoy]])</nowiki>
|----
| 821503639 || 2018-01-20T22:00:20Z || 76.72.12.85 || <nowiki>/* Former operators */</nowiki>
|----
| 821503476 || 2018-01-20T21:59:17Z || 76.72.12.85 || <nowiki>/* Former operators */</nowiki>
|----
| 819534539 || 2018-01-09T22:16:46Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 819534327 || 2018-01-09T22:15:17Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 819530533 || 2018-01-09T21:47:50Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 819530275 || 2018-01-09T21:45:58Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 819530203 || 2018-01-09T21:45:27Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 819530087 || 2018-01-09T21:44:44Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 808408763 || 2017-11-02T18:04:28Z || KolbertBot || <nowiki>Bot: [[User:KolbertBot|HTTP→HTTPS]] (v475)</nowiki>
|----
| 802070596 || 2017-09-23T20:23:12Z || BilCat || <nowiki>Reverted edits by [[Special:Contribs/79.181.128.85|79.181.128.85]] ([[User talk:79.181.128.85|talk]]) to last version by InternetArchiveBot</nowiki>
|----
| 802070310 || 2017-09-23T20:20:49Z || 79.181.128.85 || <nowiki></nowiki>
|----
| 799325820 || 2017-09-07T00:51:03Z || InternetArchiveBot || <nowiki>Rescuing 1 sources and tagging 0 as dead. #IABot (v1.5.1)</nowiki>
|----
| 791998450 || 2017-07-23T20:15:03Z || Dawnseeker2000 || <nowiki>[[MOS:DASH]], link maintenance using [[Project:AWB|AWB]]</nowiki>
|----
| 790109844 || 2017-07-11T17:38:14Z || Hohum || <nowiki>/* Other civilian operators */</nowiki>
|----
| 789997361 || 2017-07-10T23:07:48Z || 216.126.97.146 || <nowiki>/* Current airline and other operators */</nowiki>
|----
| 787732976 || 2017-06-27T06:50:16Z || Dash 7 || <nowiki>/* External links */ Dash 7 homepage moved to dedicated domain</nowiki>
|----
| 784047752 || 2017-06-06T05:01:11Z || Magic links bot || <nowiki>Replace [[Help:Magic links|magic links]] with templates per [[Special:Permalink/772743896#Future of magic links|local RfC]] and [[:mw:Requests for comment/Future of magic links|MediaWiki RfC]]</nowiki>
|----
| 783510593 || 2017-06-02T19:45:03Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 783510453 || 2017-06-02T19:43:58Z || 72.214.124.220 || <nowiki>/* Airline and other operators - past & present */</nowiki>
|----
| 783510387 || 2017-06-02T19:43:32Z || 72.214.124.220 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 782522356 || 2017-05-27T12:56:27Z || 70.50.172.235 || <nowiki></nowiki>
|----
| 781668240 || 2017-05-22T15:28:24Z || Uli Elch || <nowiki>added [[Category:Aircraft first flown in 1975]] using [[WP:HC|HotCat]]</nowiki>
|----
| 781011086 || 2017-05-18T15:03:54Z || Uli Elch || <nowiki>/* External links */ sortkey</nowiki>
|----
| 781010882 || 2017-05-18T15:02:15Z || Uli Elch || <nowiki>added [[Category:STOL aircraft]] using [[WP:HC|HotCat]]</nowiki>
|----
| 774063133 || 2017-04-06T01:58:51Z || Skyraider1 || <nowiki>Undid revision 773389835 by [[Special:Contributions/Fat pig73|Fat pig73]] ([[User talk:Fat pig73|talk]]) Good faith, but uncited, grammatically incorrect. Why is this detail noteworthy?</nowiki>
|----
| 773389835 || 2017-04-02T03:02:19Z || Fat pig73 || <nowiki>/* Operational history */</nowiki>
|----
| 772556812 || 2017-03-28T00:10:57Z || 70.67.245.113 || <nowiki>/* Operational history */ "pollution onitoring" --> "pollution monitoring"</nowiki>
|----
| 772006597 || 2017-03-24T19:33:42Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 772006550 || 2017-03-24T19:33:17Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 772006109 || 2017-03-24T19:30:25Z || 72.214.124.220 || <nowiki>/* Operational history */</nowiki>
|----
| 772006069 || 2017-03-24T19:30:07Z || 72.214.124.220 || <nowiki>/* Operational history */</nowiki>
|----
| 766069442 || 2017-02-18T01:39:35Z || 71.73.96.24 || <nowiki></nowiki>
|----
| 765907972 || 2017-02-17T02:43:39Z || 216.108.186.43 || <nowiki>/* Airline and other operators */Corrected information</nowiki>
|----
| 765682584 || 2017-02-15T20:41:29Z || 86.24.195.249 || <nowiki>/* Former operators */Added content</nowiki>
|----
| 763861493 || 2017-02-05T17:17:22Z || 207.140.164.68 || <nowiki>/* Specifications */ Changed nmi to nm. In aviation nm is used to abbreviate nautical miles. Not nmi.</nowiki>
|----
| 755023847 || 2016-12-15T20:58:55Z || 66.66.93.170 || <nowiki>/* Operational history */</nowiki>
|----
| 755023815 || 2016-12-15T20:58:42Z || 66.66.93.170 || <nowiki>/* Operational history */</nowiki>
|----
| 741645652 || 2016-09-28T20:30:15Z || 72.214.124.220 || <nowiki>/* Former operators */</nowiki>
|----
| 741645516 || 2016-09-28T20:29:31Z || 72.214.124.220 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 741645472 || 2016-09-28T20:29:18Z || 72.214.124.220 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 724355139 || 2016-06-08T18:28:31Z || Philippe 600 || <nowiki>/* Operators */ add Air Greenland to former operators</nowiki>
|----
| 720891033 || 2016-05-18T15:48:52Z || 87.236.134.114 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 720890988 || 2016-05-18T15:48:35Z || 87.236.134.114 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 715922089 || 2016-04-18T19:23:22Z || 216.126.97.146 || <nowiki>/* Former operators */</nowiki>
|----
| 715921978 || 2016-04-18T19:22:31Z || 216.126.97.146 || <nowiki></nowiki>
|----
| 713828550 || 2016-04-06T02:31:49Z || 98.14.161.97 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 712920086 || 2016-03-31T21:12:38Z || Ashley Pomeroy || <nowiki>/* Operational history */</nowiki>
|----
| 712260212 || 2016-03-28T01:24:33Z || 84.128.254.188 || <nowiki>/* Airline and other operators */Correct Informations</nowiki>
|----
| 694982664 || 2015-12-12T23:18:41Z || Dash7 || <nowiki></nowiki>
|----
| 694982099 || 2015-12-12T23:14:13Z || Dash7 || <nowiki>terminology for propeller operation corrected</nowiki>
|----
| 689439505 || 2015-11-07T05:01:36Z || Feminist || <nowiki>added [[Category:T-tail aircraft]] using [[WP:HC|HotCat]]</nowiki>
|----
| 687074881 || 2015-10-23T04:34:20Z || BilCat || <nowiki>Undid revision 687070450 by [[Special:Contributions/203.161.148.166|203.161.148.166]] ([[User talk:203.161.148.166|talk]]) - try reading the article, which makes no mention of the 5,, but does the 6</nowiki>
|----
| 687070450 || 2015-10-23T03:58:46Z || 203.161.148.166 || <nowiki>Fixed impossibility</nowiki>
|----
| 680708383 || 2015-09-12T17:34:31Z || Cacetudo || <nowiki>/* Design and development */</nowiki>
|----
| 674017989 || 2015-08-01T01:44:11Z || 172.72.73.26 || <nowiki>/* See also */ added ATR 42 link</nowiki>
|----
| 668361427 || 2015-06-23T21:37:51Z || BD2412 || <nowiki>Consensus at [[Template talk:Aviation lists#RfC: Should this navbox be removed from non-mentioned articles?]] using [[Project:AWB|AWB]]</nowiki>
|----
| 667639039 || 2015-06-19T15:01:53Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 667638844 || 2015-06-19T15:00:09Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 659963124 || 2015-04-29T23:54:40Z || Gavron || <nowiki>/* Design and development */</nowiki>
|----
| 659364373 || 2015-04-26T22:20:42Z || 24.204.208.245 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 656115891 || 2015-04-12T13:06:21Z || 68.47.115.97 || <nowiki>/* Operational history */ It originally said propjets and I corrected it to say turboprops.</nowiki>
|----
| 655208975 || 2015-04-06T16:42:13Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208873 || 2015-04-06T16:41:19Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208628 || 2015-04-06T16:39:25Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208534 || 2015-04-06T16:38:41Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208487 || 2015-04-06T16:38:21Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208333 || 2015-04-06T16:37:16Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208218 || 2015-04-06T16:36:10Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655208139 || 2015-04-06T16:35:30Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655189166 || 2015-04-06T14:03:39Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655188997 || 2015-04-06T14:02:12Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655188816 || 2015-04-06T14:00:44Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 655188586 || 2015-04-06T13:58:49Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 649431154 || 2015-03-01T21:06:55Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 649428949 || 2015-03-01T20:49:26Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 649427932 || 2015-03-01T20:41:58Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 649427711 || 2015-03-01T20:40:28Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 649426628 || 2015-03-01T20:32:13Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 649426502 || 2015-03-01T20:31:12Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 649426346 || 2015-03-01T20:30:15Z || 68.226.139.28 || <nowiki>/* Former operators */</nowiki>
|----
| 646401507 || 2015-02-09T21:05:13Z || MilborneOne || <nowiki>not reeally needed in the lead</nowiki>
|----
| 646401212 || 2015-02-09T21:03:27Z || 72.214.124.218 || <nowiki></nowiki>
|----
| 646401138 || 2015-02-09T21:02:55Z || 72.214.124.218 || <nowiki></nowiki>
|----
| 646401014 || 2015-02-09T21:02:01Z || 72.214.124.218 || <nowiki></nowiki>
|----
| 646012377 || 2015-02-07T09:02:24Z || BilCat || <nowiki>Undid revision 646010885 by [[Special:Contributions/Haddz|Haddz]] ([[User talk:Haddz|talk]]) -please discuss infobox image changes first</nowiki>
|----
| 646010885 || 2015-02-07T08:40:26Z || Haddz || <nowiki></nowiki>
|----
| 642060717 || 2015-01-11T21:19:03Z || Hawaiian717 || <nowiki>/* Operational history */ Island Air no longer serves JHM</nowiki>
|----
| 627264920 || 2014-09-27T10:41:15Z || Nigel Ish || <nowiki>/* Specifications */ revert to what the source actually says + accessibility changes</nowiki>
|----
| 627264466 || 2014-09-27T10:34:11Z || Nigel Ish || <nowiki>Undid revision 627256850 by [[Special:Contributions/Chaxterium|Chaxterium]] ([[User talk:Chaxterium|talk]]) - no it isn't - nm is an abbreviation for nanometre</nowiki>
|----
| 627256850 || 2014-09-27T08:38:48Z || Chaxterium || <nowiki>The accepted abbreviation for nautical miles is nm, not nmi.</nowiki>
|----
| 616551798 || 2014-07-11T17:35:58Z || Revent || <nowiki>Cleaning [[Category: Pages containing citation needed template with deprecated parameters]]</nowiki>
|----
| 615433266 || 2014-07-03T13:56:05Z || 108.41.39.169 || <nowiki>/* Former operators */</nowiki>
|----
| 611068005 || 2014-06-01T12:20:46Z || LittleWink || <nowiki>Disambiguating links to [[Victoria]] (link changed to [[Victoria, British Columbia]]) using [[User:Qwertyytrewqqwerty/DisamAssist|DisamAssist]].</nowiki>
|----
| 610310502 || 2014-05-27T06:36:09Z || The Bushranger || <nowiki>+[[Category:Four-engined tractor aircraft]]; +[[Category:High-wing aircraft]]; +[[Category:Turboprop aircraft]] using [[WP:HC|HotCat]]</nowiki>
|----
| 609719368 || 2014-05-22T20:39:31Z || Ahunt || <nowiki>/* Operational history */ wikilinking</nowiki>
|----
| 609718698 || 2014-05-22T20:33:53Z || Ahunt || <nowiki>wording to eliminate the need for brackets</nowiki>
|----
| 609712363 || 2014-05-22T19:41:16Z || 66.185.200.1 || <nowiki></nowiki>
|----
| 609711502 || 2014-05-22T19:33:33Z || 66.185.200.1 || <nowiki></nowiki>
|----
| 609711234 || 2014-05-22T19:31:12Z || 66.185.200.1 || <nowiki></nowiki>
|----
| 609710903 || 2014-05-22T19:28:19Z || 66.185.200.1 || <nowiki>/* See also */</nowiki>
|----
| 608206519 || 2014-05-12T11:11:54Z || Chaxterium || <nowiki>/* Specifications */</nowiki>
|----
| 608206405 || 2014-05-12T11:10:09Z || Chaxterium || <nowiki>/* Specifications */ Corrected range and Ceiling. Max Certificated ceiling is 20400 with passengers and range is closer to 1000nm depending on fuel.</nowiki>
|----
| 604609023 || 2014-04-17T15:58:54Z || MilborneOne || <nowiki>Undid revision 604489688 by [[Special:Contributions/Bfd1942|Bfd1942]] ([[User talk:Bfd1942|talk]]) dont think actual location is relevant for the lead image</nowiki>
|----
| 604489688 || 2014-04-16T19:21:38Z || Bfd1942 || <nowiki>Added information about image</nowiki>
|----
| 598344117 || 2014-03-06T02:16:34Z || The Bushranger || <nowiki>+navbox</nowiki>
|----
| 597444835 || 2014-02-27T23:18:57Z || 199.198.251.109 || <nowiki>/* Military operators */</nowiki>
|----
| 593670514 || 2014-02-03T02:15:23Z || OhanaUnited || <nowiki>/* Operational history */ fix ref</nowiki>
|----
| 593669819 || 2014-02-03T02:07:33Z || OhanaUnited || <nowiki>/* Operational history */ last dash 7</nowiki>
|----
| 592899379 || 2014-01-29T02:54:16Z || WPGA2345 || <nowiki>Fixing [[Wikipedia:Disambiguation pages with links|links to disambiguation pages]] (page is nominated for disambiguation), replaced: [[undercarriage]] → [[Landing gear|undercarriage]] using [[Project:AWB|AWB]]</nowiki>
|----
| 583113279 || 2013-11-24T17:04:47Z || Ulric1313 || <nowiki>dab</nowiki>
|----
| 579677263 || 2013-10-31T23:49:20Z || 167.154.149.53 || <nowiki>/* Design and development */</nowiki>
|----
| 579631813 || 2013-10-31T16:46:22Z || Ahunt || <nowiki>Undid revision 578118300 by [[Special:Contributions/212.30.16.202|212.30.16.202]] ([[User talk:212.30.16.202|talk]])</nowiki>
|----
| 578173539 || 2013-10-21T21:49:02Z || 216.67.179.218 || <nowiki>/* Former operators */</nowiki>
|----
| 578118300 || 2013-10-21T14:34:13Z || 212.30.16.202 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 573325503 || 2013-09-17T14:03:21Z || 24.8.188.199 || <nowiki>/* Former operators */ Added Trans World Express (formerly Pan Am Express) knowledge as a former employee</nowiki>
|----
| 572063555 || 2013-09-08T15:00:10Z || 119.224.31.121 || <nowiki>/* Design and development */</nowiki>
|----
| 565686903 || 2013-07-25T00:51:02Z || Nimbus227 || <nowiki>/* In popular culture */ Rm uncited trivia</nowiki>
|----
| 564514036 || 2013-07-16T14:37:19Z || 72.1.194.50 || <nowiki>/* Operational history */</nowiki>
|----
| 559526710 || 2013-06-12T07:32:50Z || 777sms || <nowiki></nowiki>
|----
| 559526646 || 2013-06-12T07:32:08Z || 777sms || <nowiki></nowiki>
|----
| 559526562 || 2013-06-12T07:31:12Z || 777sms || <nowiki>Infobox aircraft begin fix using [[Project:AWB|AWB]]</nowiki>
|----
| 556239187 || 2013-05-22T09:25:28Z || Jimp || <nowiki></nowiki>
|----
| 552595557 || 2013-04-28T17:40:28Z || AnomieBOT || <nowiki>Dating maintenance tags: {{Cn}}</nowiki>
|----
| 552592793 || 2013-04-28T17:20:20Z || Fudoreaper || <nowiki>/* Design and development */ add CN on dubiously shore figure</nowiki>
|----
| 551154726 || 2013-04-19T16:34:43Z || Nigel Ish || <nowiki>/* Specifications */ from source</nowiki>
|----
| 551153558 || 2013-04-19T16:25:28Z || Nigel Ish || <nowiki>/* References */ add ref</nowiki>
|----
| 540422666 || 2013-02-26T00:40:54Z || Addbot || <nowiki>[[User:Addbot|Bot:]] Migrating 11 interwiki links, now provided by [[Wikipedia:Wikidata|Wikidata]] on [[d:q178487]] ([[User talk:Addbot|Report Errors]])</nowiki>
|----
| 539578142 || 2013-02-22T01:45:06Z || 68.226.137.168 || <nowiki>/* Operational history */</nowiki>
|----
| 539478261 || 2013-02-21T18:12:25Z || LittleWink || <nowiki>link [[GE Dash 7 Series]] in hatnote</nowiki>
|----
| 535470916 || 2013-01-29T06:16:12Z || 66.76.18.251 || <nowiki></nowiki>
|----
| 535470809 || 2013-01-29T06:14:55Z || 66.76.18.251 || <nowiki></nowiki>
|----
| 535470748 || 2013-01-29T06:14:06Z || 66.76.18.251 || <nowiki></nowiki>
|----
| 532431144 || 2013-01-10T21:35:44Z || 72.214.124.218 || <nowiki>/* See also */</nowiki>
|----
| 532430973 || 2013-01-10T21:34:29Z || 72.214.124.218 || <nowiki>/* See also */</nowiki>
|----
| 532430850 || 2013-01-10T21:33:46Z || 72.214.124.218 || <nowiki>/* See also */</nowiki>
|----
| 532430286 || 2013-01-10T21:29:55Z || 72.214.124.218 || <nowiki>/* Airline and other operators */</nowiki>
|----
| 532430145 || 2013-01-10T21:28:56Z || 72.214.124.218 || <nowiki>/* Airline operators */</nowiki>
|----
| 532429955 || 2013-01-10T21:27:42Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 531802406 || 2013-01-07T16:25:14Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 531802311 || 2013-01-07T16:24:34Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 531732697 || 2013-01-07T04:22:48Z || Bzuk || <nowiki>recently, some changes are required to the reference notations to allow machine-readable technology to work, some other areas addressed</nowiki>
|----
| 531729699 || 2013-01-07T03:54:49Z || OhanaUnited || <nowiki>/* Variants */ close bracket</nowiki>
|----
| 531596240 || 2013-01-06T10:02:30Z || 41.79.25.123 || <nowiki>/* Design and development */ Changed to present tense since the aircraft is still in operation.</nowiki>
|----
| 528602638 || 2012-12-18T07:37:52Z || 216.126.100.26 || <nowiki>/* Airline operators */</nowiki>
|----
| 525170455 || 2012-11-27T17:28:25Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 525170220 || 2012-11-27T17:27:10Z || 72.214.124.218 || <nowiki>/* Design and development */</nowiki>
|----
| 525169452 || 2012-11-27T17:22:13Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 525169283 || 2012-11-27T17:21:05Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 524880422 || 2012-11-26T00:59:54Z || Onward2 || <nowiki></nowiki>
|----
| 517657935 || 2012-10-14T01:03:17Z || 70.189.33.194 || <nowiki>/* Former operators */</nowiki>
|----
| 517645723 || 2012-10-13T23:08:15Z || 70.189.33.194 || <nowiki>/* Former operators */</nowiki>
|----
| 517645603 || 2012-10-13T23:07:13Z || 70.189.33.194 || <nowiki>/* Former operators */</nowiki>
|----
| 517645520 || 2012-10-13T23:06:25Z || 70.189.33.194 || <nowiki>/* Former operators */</nowiki>
|----
| 517645371 || 2012-10-13T23:05:09Z || 70.189.33.194 || <nowiki>/* See also */</nowiki>
|----
| 517421625 || 2012-10-12T16:12:11Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 517421251 || 2012-10-12T16:09:19Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 517420912 || 2012-10-12T16:06:41Z || 72.214.124.218 || <nowiki>/* Design and development */</nowiki>
|----
| 517390727 || 2012-10-12T13:12:57Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 517389109 || 2012-10-12T13:04:46Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 517388777 || 2012-10-12T13:03:20Z || 72.214.124.218 || <nowiki>/* Design and development */</nowiki>
|----
| 516885705 || 2012-10-09T20:50:07Z || 72.214.124.218 || <nowiki>/* Operational history */</nowiki>
|----
| 516539879 || 2012-10-07T22:22:26Z || Niceguyedc || <nowiki>[[:en:WP:CLEANER|WPCleaner]] v1.18 - Repaired 1 link to disambiguation page - [[WP:DPL|(You can help)]] - [[Dash 8]]</nowiki>
|----
| 515053769 || 2012-09-28T20:10:53Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 515019199 || 2012-09-28T15:55:36Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 515018009 || 2012-09-28T15:46:34Z || 72.214.124.218 || <nowiki>/* Former operators */</nowiki>
|----
| 503529804 || 2012-07-22T02:36:55Z || 66.135.229.201 || <nowiki>/* Former operators */</nowiki>
|----
| 492858697 || 2012-05-16T13:07:14Z || Irwan1834 || <nowiki>/* Former operators */</nowiki>
|----
| 492832401 || 2012-05-16T08:21:47Z || Irwan1834 || <nowiki>/* Airline operators */</nowiki>
|----
| 491684197 || 2012-05-09T22:02:59Z || Helpful Pixie Bot || <nowiki>ISBNs (Build KE)</nowiki>
|----
| 491024912 || 2012-05-06T17:35:52Z || Thegraciousfew || <nowiki>/* In popular culture */ wilco</nowiki>
|----
| 491024652 || 2012-05-06T17:34:18Z || Thegraciousfew || <nowiki>/* In popular culture */ wilco</nowiki>
|----
| 491023989 || 2012-05-06T17:30:23Z || Thegraciousfew || <nowiki>/* Specifications */ wilco</nowiki>
|----
| 489648867 || 2012-04-28T16:51:13Z || Irwan1834 || <nowiki>/* Former operators */</nowiki>
|----
| 489616991 || 2012-04-28T12:47:50Z || Irwan1834 || <nowiki></nowiki>
|----
| 489616580 || 2012-04-28T12:43:55Z || 203.82.80.11 || <nowiki>/* Airline operators */</nowiki>
|----
| 489600669 || 2012-04-28T09:53:37Z || 203.82.82.81 || <nowiki>/* Operators */</nowiki>
|----
| 488572073 || 2012-04-21T23:39:59Z || OhanaUnited || <nowiki>/* Airline operators */ fix</nowiki>
|----
| 487361996 || 2012-04-14T17:01:02Z || 67.162.140.83 || <nowiki>/* Former operators */</nowiki>
|----
| 482406492 || 2012-03-17T18:17:13Z || 67.168.16.82 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 482405743 || 2012-03-17T18:12:20Z || 67.168.16.82 || <nowiki>/* Design and development */</nowiki>
|----
| 480274365 || 2012-03-05T05:43:08Z || ShipFan || <nowiki>/* Former operators */</nowiki>
|----
| 471171438 || 2012-01-13T17:13:59Z || 199.198.251.106 || <nowiki></nowiki>
|----
| 469925288 || 2012-01-06T16:38:06Z || RedBot || <nowiki>r2.5.2) (Robot: Adding [[he:דאש 7]]</nowiki>
|----
| 469904400 || 2012-01-06T14:27:06Z || 79.180.147.165 || <nowiki>/* Former operators */</nowiki>
|----
| 469401646 || 2012-01-03T21:57:46Z || ZéroBot || <nowiki>r2.7.1) (Robot: Adding [[id:De Havilland Canada Dash 7]]</nowiki>
|----
| 462481238 || 2011-11-25T23:44:35Z || Shabtai143 || <nowiki>/* Former operators */</nowiki>
|----
| 462481188 || 2011-11-25T23:44:13Z || Shabtai143 || <nowiki>/* Airline operators */</nowiki>
|----
| 462481113 || 2011-11-25T23:43:37Z || Shabtai143 || <nowiki>/* Former operators */</nowiki>
|----
| 462481006 || 2011-11-25T23:42:46Z || Shabtai143 || <nowiki>/* Airline operators */</nowiki>
|----
| 461532786 || 2011-11-20T03:15:10Z || 50.92.138.91 || <nowiki>/* Former operators */</nowiki>
|----
| 460476334 || 2011-11-13T18:34:26Z || Edward || <nowiki>link [[belly landing]] using [[User:Edward/Find link|Find link]]</nowiki>
|----
| 458309820 || 2011-10-31T15:29:09Z || Degen Earthfast || <nowiki>/* Accidents and incidents */ Added NL wikilink</nowiki>
|----
| 455262012 || 2011-10-12T20:20:19Z || Arsenikk || <nowiki>better image for infobox</nowiki>
|----
| 454753833 || 2011-10-09T19:32:00Z || Cydebot || <nowiki>Robot - Removing category STOL per [[WP:CFD|CFD]] at [[Wikipedia:Categories for discussion/Log/2011 September 28]].</nowiki>
|----
| 453769097 || 2011-10-03T20:50:53Z || Cydebot || <nowiki>Robot - Moving category Canadian airliners 1970-1979 to [[:Category:Canadian airliners 1970–1979]] per [[WP:CFD|CFD]] at [[Wikipedia:Categories for discussion/Log/2011 September 20]].</nowiki>
|----
| 453566206 || 2011-10-02T18:34:58Z || 96.54.235.0 || <nowiki>/* Variants */ switched weighs around to match rest of list</nowiki>
|----
| 451132828 || 2011-09-18T12:13:05Z || BilCat || <nowiki>Reverted to last good version before addition of questionable links by same user via multiple IPs</nowiki>
|----
| 451132389 || 2011-09-18T12:09:23Z || BilCat || <nowiki>[[Help:Reverting|Reverted]] edits by [[Special:Contributions/118.216.45.28|118.216.45.28]] ([[User talk:118.216.45.28|talk]]) to last version by 118.218.208.5</nowiki>
|----
| 451130125 || 2011-09-18T11:47:47Z || 118.216.45.28 || <nowiki>/* See also */</nowiki>
|----
| 451129479 || 2011-09-18T11:41:12Z || 118.216.45.28 || <nowiki>/* See also */</nowiki>
|----
| 451127128 || 2011-09-18T11:18:14Z || 118.216.45.28 || <nowiki>/* See also */</nowiki>
|----
| 450957101 || 2011-09-17T12:04:10Z || 118.218.208.5 || <nowiki></nowiki>
|----
| 450433779 || 2011-09-14T08:21:23Z || 203.88.70.114 || <nowiki>/* Airline operators */</nowiki>
|----
| 446465926 || 2011-08-24T10:20:53Z || Bloggins762 || <nowiki>Undid revision 446465620 by [[Special:Contributions/Bloggins762|Bloggins762]] ([[User talk:Bloggins762|talk]])</nowiki>
|----
| 446465620 || 2011-08-24T10:18:01Z || Bloggins762 || <nowiki>Changed Canadian Forces to RCAF, as per recent air force policy, aircraft are now operated by the Royal Canadian Air Force</nowiki>
|----
| 444934228 || 2011-08-15T07:29:05Z || 46.120.78.211 || <nowiki>/* Airline operators */</nowiki>
|----
| 440303761 || 2011-07-19T13:06:21Z || Bzuk || <nowiki>kinda dicey addition...</nowiki>
|----
| 440299276 || 2011-07-19T12:31:03Z || Mikeepav || <nowiki></nowiki>
|----
| 439012799 || 2011-07-12T01:53:40Z || 213.246.88.188 || <nowiki>/* Specifications */ caption</nowiki>
|----
| 437992650 || 2011-07-06T04:04:10Z || 174.112.189.95 || <nowiki></nowiki>
|----
| 435941884 || 2011-06-24T08:09:36Z || Luckas-bot || <nowiki>r2.7.1) (robot Adding: [[sv:De Havilland Canada Dash 7]]</nowiki>
|----
| 430290300 || 2011-05-22T03:08:34Z || Chaxterium || <nowiki>/* Design and development */ Re-worded the paragraph on flaps and spoilers.</nowiki>
|----
| 430211872 || 2011-05-21T16:21:54Z || Chaxterium || <nowiki>/* Design and development */</nowiki>
|----
| 430210465 || 2011-05-21T16:11:29Z || Chaxterium || <nowiki>/* Design and development */</nowiki>
|----
| 430206357 || 2011-05-21T15:41:29Z || 125.213.212.194 || <nowiki>/* Design and development */ Minor correction of flap data.</nowiki>
|----
| 429951334 || 2011-05-19T21:55:03Z || OhanaUnited || <nowiki>/* Specifications */ passengers</nowiki>
|----
| 429951257 || 2011-05-19T21:54:33Z || OhanaUnited || <nowiki>/* Specifications */ capacity</nowiki>
|----
| 429175041 || 2011-05-15T02:53:15Z || 67.185.138.28 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 429174978 || 2011-05-15T02:52:36Z || 67.185.138.28 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 424887095 || 2011-04-19T17:32:54Z || Saibo || <nowiki>Image:Dash 7.JPG → File:Voyageur Airways Dash 7 in Winnipeg, 2005.jpg in Commons</nowiki>
|----
| 423845230 || 2011-04-13T12:11:54Z || CambridgeBayWeather || <nowiki>/* Variants */ Visible anchor for incoming link</nowiki>
|----
| 422067165 || 2011-04-03T00:56:26Z || Bobscola || <nowiki>former operators - USA - in wrong sort order, fixed</nowiki>
|----
| 422066911 || 2011-04-03T00:54:27Z || Bobscola || <nowiki>list Air Wisconsin, Henson & Ransome as former operators</nowiki>
|----
| 422066580 || 2011-04-03T00:51:48Z || Bobscola || <nowiki>removed Ransome Airlines, no longer exists</nowiki>
|----
| 422066144 || 2011-04-03T00:48:11Z || Bobscola || <nowiki>remove Henson Airlines as a DHC-7 operator. Henson is now braned as 'Piedmont Airlines' and flies only DHC-8 's</nowiki>
|----
| 422065743 || 2011-04-03T00:44:45Z || Bobscola || <nowiki>removed Air Wisconsin as a DHC-7 operator. Both the airlines website and wikipedia article state only CRJ's now being used</nowiki>
|----
| 418752045 || 2011-03-14T08:52:26Z || JackieBot || <nowiki>r2.6.5) (robot Adding: [[ru:De Havilland Canada Dash 7]]</nowiki>
|----
| 417177508 || 2011-03-05T00:44:45Z || ImageRemovalBot || <nowiki>Removing deleted [[:File:De Havilland Canada DHC-7 Dash-7 Pelita Air PK-PSX.JPG|image]]</nowiki>
|----
| 415848893 || 2011-02-25T11:30:31Z || 2ULF4N || <nowiki>/* Airline operators */</nowiki>
|----
| 415846899 || 2011-02-25T11:11:37Z || 2ULF4N || <nowiki>/* Airline operators */</nowiki>
|----
| 415008711 || 2011-02-20T21:04:38Z || BilCat || <nowiki>Undid revision 415002524 by [[Special:Contributions/Degen Earthfast|Degen Earthfast]] ([[User talk:Degen Earthfast|talk]]) - reverted - broke infobox</nowiki>
|----
| 415002524 || 2011-02-20T20:23:42Z || Degen Earthfast || <nowiki></nowiki>
|----
| 410635442 || 2011-01-28T21:21:03Z || Bzuk || <nowiki>reworded</nowiki>
|----
| 410622326 || 2011-01-28T20:08:00Z || 70.25.113.146 || <nowiki>/* Operational history */ Corrected capitalization</nowiki>
|----
| 410030965 || 2011-01-25T20:19:42Z || 64.25.167.130 || <nowiki>/* Airline operators */</nowiki>
|----
| 407778271 || 2011-01-14T03:36:10Z || 2Q || <nowiki>/* External links */</nowiki>
|----
| 406338029 || 2011-01-06T19:59:30Z || 24.67.36.194 || <nowiki>/* Design and development */</nowiki>
|----
| 405843235 || 2011-01-04T07:05:14Z || 24.67.36.194 || <nowiki>/* Design and development */</nowiki>
|----
| 399895327 || 2010-12-01T09:58:58Z || Llb9977 || <nowiki>/* Variants */</nowiki>
|----
| 399895176 || 2010-12-01T09:57:12Z || Llb9977 || <nowiki></nowiki>
|----
| 399069708 || 2010-11-27T03:14:42Z || The Bushranger || <nowiki>−[[Category:Propeller aircraft]]; −[[Category:High wing aircraft]]; −[[Category:Multi-engine aircraft]] using [[WP:HC|HotCat]]</nowiki>
|----
| 397829520 || 2010-11-20T08:14:58Z || CambridgeBayWeather || <nowiki>Wrong line</nowiki>
|----
| 397828418 || 2010-11-20T08:04:46Z || CambridgeBayWeather || <nowiki>Adding tag for incoming link</nowiki>
|----
| 396016694 || 2010-11-10T22:11:42Z || 70.74.160.14 || <nowiki></nowiki>
|----
| 396016043 || 2010-11-10T22:07:55Z || 70.74.160.14 || <nowiki>Added Wardair to Cilvilian Operators</nowiki>
|----
| 394598321 || 2010-11-03T15:25:39Z || 109.67.29.26 || <nowiki></nowiki>
|----
| 393404163 || 2010-10-28T11:29:05Z || MilborneOne || <nowiki>Undid revision 393389451 by [[Special:Contributions/Xmss|Xmss]] ([[User talk:Xmss|talk]])we already have an Air Greenland image</nowiki>
|----
| 393389451 || 2010-10-28T09:23:30Z || Xmss || <nowiki>/* Operational history */</nowiki>
|----
| 387846254 || 2010-09-30T03:11:48Z || 213.246.94.144 || <nowiki>/* Former operators */ "Eurocity Express" was London City Airways' original name</nowiki>
|----
| 384620925 || 2010-09-13T18:00:44Z || 24.207.15.80 || <nowiki>/* Former operators */</nowiki>
|----
| 383986352 || 2010-09-10T08:09:03Z || Againme || <nowiki>+accent mark</nowiki>
|----
| 380196564 || 2010-08-21T19:24:29Z || JcHnd || <nowiki>/* Former operators */</nowiki>
|----
| 377640881 || 2010-08-07T12:54:14Z || 207.148.32.132 || <nowiki>/* Military operators */</nowiki>
|----
| 374219304 || 2010-07-19T00:11:58Z || Bzuk || <nowiki>all that is needed</nowiki>
|----
| 374211789 || 2010-07-18T23:18:38Z || 121.222.13.30 || <nowiki></nowiki>
|----
| 368344146 || 2010-06-16T07:43:55Z || 153.111.60.15 || <nowiki></nowiki>
|----
| 367913795 || 2010-06-14T05:41:13Z || BilCat || <nowiki>Thumb sizing removed per MOS</nowiki>
|----
| 367913708 || 2010-06-14T05:40:25Z || BilCat || <nowiki>Removed thumb sizing</nowiki>
|----
| 367913409 || 2010-06-14T05:37:50Z || BilCat || <nowiki>Undid revision 367912921 by [[Special:Contributions/72.145.157.36|72.145.157.36]] ([[User talk:72.145.157.36|talk]]) - contraditory changes</nowiki>
|----
| 367912921 || 2010-06-14T05:33:31Z || 72.145.157.36 || <nowiki></nowiki>
|----
| 367130529 || 2010-06-10T03:41:09Z || 216.108.4.71 || <nowiki>Made the description more accurate.</nowiki>
|----
| 364279384 || 2010-05-26T11:10:23Z || Algkalv || <nowiki>Undid revision 364272680 by [[Special:Contributions/59.92.249.114|59.92.249.114]] ([[User talk:59.92.249.114|talk]]) rvv</nowiki>
|----
| 364272680 || 2010-05-26T10:03:34Z || 59.92.249.114 || <nowiki>/* Specifications */</nowiki>
|----
| 363755562 || 2010-05-23T16:39:54Z || 99.227.208.197 || <nowiki>/* Former operators */ Added City Express and alphabetised the list by country to clean it up for you. :)</nowiki>
|----
| 362978007 || 2010-05-19T09:37:48Z || RuthAS || <nowiki>/* Operational history */ add image of London City Airways DHC-7 in 1988</nowiki>
|----
| 360039522 || 2010-05-04T10:45:20Z || Cydebot || <nowiki>Robot - Moving category Multiple engine aircraft to Multi-engine aircraft per [[WP:CFD|CFD]] at [[Wikipedia:Categories for discussion/Log/2010 April 23]].</nowiki>
|----
| 357603547 || 2010-04-22T11:34:17Z || Algkalv || <nowiki>/* Variants */ +photo (passenger/cargo)</nowiki>
|----
| 355749750 || 2010-04-13T13:26:37Z || Vytal || <nowiki>/* Accidents and incidents */ prep</nowiki>
|----
| 354244467 || 2010-04-06T03:31:53Z || Chris the speller || <nowiki>number fmt</nowiki>
|----
| 350409275 || 2010-03-17T15:03:49Z || WilliamJE || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 349280874 || 2010-03-11T19:42:44Z || Arsenikk || <nowiki>/* Accidents and incidents */ dab</nowiki>
|----
| 349084100 || 2010-03-10T21:36:56Z || Cobra5000 || <nowiki>/* Former operators */</nowiki>
|----
| 349083581 || 2010-03-10T21:34:36Z || Cobra5000 || <nowiki>/* Airline operators */</nowiki>
|----
| 345537854 || 2010-02-21T23:39:51Z || Gaius Cornelius || <nowiki>Tidy references and other fixes using [[Project:AWB|AWB]]</nowiki>
|----
| 338518850 || 2010-01-18T08:01:30Z || BilCat || <nowiki>Corrections</nowiki>
|----
| 338518267 || 2010-01-18T07:54:32Z || BilCat || <nowiki>Added developed into field to Infobox</nowiki>
|----
| 338510958 || 2010-01-18T06:38:55Z || 85.200.224.138 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 338510930 || 2010-01-18T06:38:38Z || 85.200.224.138 || <nowiki>/* Accidents and incidents */ spelling error</nowiki>
|----
| 335588224 || 2010-01-03T05:40:35Z || 72.40.108.82 || <nowiki>/* Former operators */</nowiki>
|----
| 335430190 || 2010-01-02T09:06:00Z || 115.133.29.168 || <nowiki>/* Airline operators */</nowiki>
|----
| 332253934 || 2009-12-17T09:36:54Z || 78.32.159.25 || <nowiki>/* Airline operators */ US Army listed as an 'Airline Operator'</nowiki>
|----
| 331879232 || 2009-12-15T21:22:51Z || Ahunt || <nowiki>/* Variants */ formatting</nowiki>
|----
| 331653291 || 2009-12-14T18:23:48Z || 192.172.8.13 || <nowiki>/* Accidents and incidents */ -- spelling</nowiki>
|----
| 330627217 || 2009-12-09T07:30:20Z || SmackBot || <nowiki>Date maintenance tags and general fixes</nowiki>
|----
| 330247225 || 2009-12-07T14:36:25Z || BilCat || <nowiki>Removed uncited claims with old fact tags</nowiki>
|----
| 330231083 || 2009-12-07T12:10:59Z || Bzuk || <nowiki>[[WP:UNDO|Undid]] revision 330175285 by [[Special:Contributions/Degen Earthfast|Degen Earthfast]] ([[User talk:Degen Earthfast|talk]]) Revert AGF move that essentially creates an unnecessary section</nowiki>
|----
| 330175285 || 2009-12-07T03:07:37Z || Degen Earthfast || <nowiki>/* Operational history */</nowiki>
|----
| 329949274 || 2009-12-05T22:43:11Z || 190.148.101.109 || <nowiki>/* Airline operators */</nowiki>
|----
| 329443647 || 2009-12-03T12:25:32Z || Bzuk || <nowiki>In respect to last edits, units given ala Canadian standard</nowiki>
|----
| 329443205 || 2009-12-03T12:21:02Z || Bzuk || <nowiki>[[Help:Reverting|Reverted]] edits by [[Special:Contributions/158.39.82.140|158.39.82.140]] ([[User talk:158.39.82.140|talk]]) to last version by 190.37.163.222</nowiki>
|----
| 329438164 || 2009-12-03T11:31:40Z || 158.39.82.140 || <nowiki></nowiki>
|----
| 329437900 || 2009-12-03T11:28:55Z || 158.39.82.140 || <nowiki></nowiki>
|----
| 322233368 || 2009-10-26T23:04:50Z || 190.37.163.222 || <nowiki>/* Airline operators */</nowiki>
|----
| 320896038 || 2009-10-19T22:53:03Z || 86.129.164.120 || <nowiki>/* Other civilian operators */</nowiki>
|----
| 320701367 || 2009-10-19T00:15:52Z || Bzuk || <nowiki>general cleanup, cites, refs, more to come</nowiki>
|----
| 320595659 || 2009-10-18T13:39:51Z || Degen Earthfast || <nowiki>added wikiolinks</nowiki>
|----
| 319246580 || 2009-10-11T15:55:45Z || Geo Swan || <nowiki>/* Military operators */</nowiki>
|----
| 318450103 || 2009-10-07T13:26:48Z || 213.227.161.137 || <nowiki>/* Former operators */ Tyrolean Airways added</nowiki>
|----
| 318450014 || 2009-10-07T13:26:10Z || 213.227.161.137 || <nowiki>/* Former operators */</nowiki>
|----
| 312512624 || 2009-09-08T02:23:10Z || 72.192.44.104 || <nowiki>Ransome Airlines was a former operator of 8 Dash 7 aircraft</nowiki>
|----
| 311149502 || 2009-08-31T20:57:43Z || Arsenikk || <nowiki>/* External links */ commonscat</nowiki>
|----
| 308343965 || 2009-08-16T19:32:55Z || Reedy || <nowiki>clean up using [[Project:AutoWikiBrowser|AWB]]</nowiki>
|----
| 300631624 || 2009-07-06T17:32:24Z || LeadSongDog || <nowiki>/* Accidents and incidents */ sp, cite</nowiki>
|----
| 299701230 || 2009-07-01T14:56:33Z || Chris the speller || <nowiki>sp, date fmt</nowiki>
|----
| 296433565 || 2009-06-14T22:28:33Z || DrilBot || <nowiki>[[WP:CHECKWIKI|Check Wikipedia]] cleanup ([[User:DrilBot/Summaries#Links|links]]) + [[WP:GENFIXES|gen. fixes]]</nowiki>
|----
| 295494615 || 2009-06-10T01:42:14Z || 72.38.201.11 || <nowiki>/* Design and development */</nowiki>
|----
| 295460449 || 2009-06-09T22:09:59Z || 77.28.6.56 || <nowiki>/* Operators */ added new sub-heading for former operators; added adria airways from slovenia</nowiki>
|----
| 292873987 || 2009-05-28T13:21:14Z || Arntjay || <nowiki>Misspelled operators name</nowiki>
|----
| 292681605 || 2009-05-27T15:21:31Z || 77.238.214.221 || <nowiki></nowiki>
|----
| 290548433 || 2009-05-17T17:51:44Z || 210.213.124.237 || <nowiki>/* Airline operators */</nowiki>
|----
| 290154158 || 2009-05-15T19:43:27Z || DumZiBoT || <nowiki>robot Modifying: [[ja:デ・ハビランド・カナダ DHC-7]]</nowiki>
|----
| 289563454 || 2009-05-12T22:42:29Z || Quadell || <nowiki>:Arkia de Havilland Canada DHC-7 4X-AHH.JPG => :Arkia de Havilland Canada DHC-7 4X-AHH.jpg (using identical image from Commons instead of local image) | Cleaned up using [[WP:AutoEd|AutoEd]] | [[wp:datescript]]-assisted date/terms audit; see [[wp:unl</nowiki>
|----
| 282169514 || 2009-04-06T19:10:53Z || Wuhwuzdat || <nowiki>disambig hat, dash 7 locomotives</nowiki>
|----
| 277950896 || 2009-03-17T21:00:38Z || Keld274 || <nowiki>/* Operational history */</nowiki>
|----
| 277949900 || 2009-03-17T20:56:01Z || Keld274 || <nowiki>/* Variants */</nowiki>
|----
| 277949026 || 2009-03-17T20:51:54Z || Keld274 || <nowiki>/* Other civilian operators */</nowiki>
|----
| 277948320 || 2009-03-17T20:48:25Z || Keld274 || <nowiki>/* Operational history */</nowiki>
|----
| 276139955 || 2009-03-09T23:09:38Z || 86.0.18.215 || <nowiki>/* Airline operators */</nowiki>
|----
| 276138969 || 2009-03-09T23:05:00Z || 86.0.18.215 || <nowiki>/* Airline operators */</nowiki>
|----
| 274646185 || 2009-03-03T08:50:02Z || SassoBot || <nowiki>robot Modifying: [[ja:デ・ハビランド・カナダ DHC-7]]</nowiki>
|----
| 273679712 || 2009-02-27T16:27:43Z || DuncanHill || <nowiki>/* Accidents and incidents */ correct [[Ashburton]] to [[Ashburton, Devon]]</nowiki>
|----
| 272784578 || 2009-02-23T19:42:19Z || Bzuk || <nowiki>/* References */ create sub-sets</nowiki>
|----
| 272784116 || 2009-02-23T19:40:30Z || Bzuk || <nowiki>/* References */ compacting</nowiki>
|----
| 272777142 || 2009-02-23T19:08:00Z || MilborneOne || <nowiki>/* Military operators */ add notes</nowiki>
|----
| 272038884 || 2009-02-20T09:54:06Z || TXiKiBoT || <nowiki>robot Modifying: [[es:De Havilland Canada Dash 7]]</nowiki>
|----
| 271923606 || 2009-02-19T21:42:31Z || 190.224.157.52 || <nowiki>/* External links */</nowiki>
|----
| 271428351 || 2009-02-17T21:42:51Z || 199.198.223.106 || <nowiki>/* Variants */</nowiki>
|----
| 271372768 || 2009-02-17T17:15:14Z || 199.198.223.106 || <nowiki>/* Airline operators */ edit</nowiki>
|----
| 271372183 || 2009-02-17T17:11:59Z || 199.198.223.106 || <nowiki>/* Airline operators */ edit</nowiki>
|----
| 271372105 || 2009-02-17T17:11:41Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271371890 || 2009-02-17T17:10:42Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271371746 || 2009-02-17T17:10:01Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271371402 || 2009-02-17T17:08:10Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271371178 || 2009-02-17T17:07:01Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271371094 || 2009-02-17T17:06:35Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271371031 || 2009-02-17T17:06:09Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271370867 || 2009-02-17T17:05:18Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271370513 || 2009-02-17T17:03:16Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271370416 || 2009-02-17T17:02:48Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271370374 || 2009-02-17T17:02:35Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271370326 || 2009-02-17T17:02:18Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271370272 || 2009-02-17T17:01:59Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271369940 || 2009-02-17T16:59:51Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271369834 || 2009-02-17T16:59:16Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271369769 || 2009-02-17T16:59:01Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271369679 || 2009-02-17T16:58:34Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271369446 || 2009-02-17T16:57:15Z || 199.198.223.106 || <nowiki>/* Airline operators */</nowiki>
|----
| 271341141 || 2009-02-17T14:12:17Z || Bunnyhop11 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271331554 || 2009-02-17T12:57:12Z || 72.138.43.177 || <nowiki>/* Airline operators */</nowiki>
|----
| 271331417 || 2009-02-17T12:56:04Z || 72.138.43.177 || <nowiki>/* Airline operators */</nowiki>
|----
| 271331196 || 2009-02-17T12:54:19Z || 72.138.43.177 || <nowiki>/* Airline operators */</nowiki>
|----
| 271331012 || 2009-02-17T12:52:42Z || 72.138.43.177 || <nowiki>/* Airline operators */</nowiki>
|----
| 271330506 || 2009-02-17T12:48:36Z || 72.138.43.177 || <nowiki>/* Other civilian operators */</nowiki>
|----
| 271329953 || 2009-02-17T12:43:57Z || 72.138.43.177 || <nowiki>/* Military operators */</nowiki>
|----
| 271329905 || 2009-02-17T12:43:36Z || 72.138.43.177 || <nowiki>/* Variants */</nowiki>
|----
| 271291983 || 2009-02-17T06:21:57Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271291064 || 2009-02-17T06:14:25Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271290928 || 2009-02-17T06:13:22Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271290780 || 2009-02-17T06:12:10Z || 72.138.43.177 || <nowiki>/* Variants */</nowiki>
|----
| 271290171 || 2009-02-17T06:07:19Z || 72.138.43.177 || <nowiki>/* Variants */</nowiki>
|----
| 271289990 || 2009-02-17T06:05:54Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271289920 || 2009-02-17T06:05:22Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271289263 || 2009-02-17T06:00:24Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */ minor edits</nowiki>
|----
| 271289001 || 2009-02-17T05:58:28Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271288955 || 2009-02-17T05:58:02Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271288930 || 2009-02-17T05:57:47Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */ edits</nowiki>
|----
| 271288553 || 2009-02-17T05:54:49Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 271288478 || 2009-02-17T05:54:08Z || 72.138.43.177 || <nowiki>/* Accidents and incidents */ add incident details</nowiki>
|----
| 270533835 || 2009-02-13T21:50:07Z || MilborneOne || <nowiki>/* Accidents and incidents */ add variants</nowiki>
|----
| 270528298 || 2009-02-13T21:23:40Z || 76.92.203.240 || <nowiki>/* Operational history */ corrected spelling</nowiki>
|----
| 270527046 || 2009-02-13T21:18:09Z || 76.92.203.240 || <nowiki>Updated ownership information</nowiki>
|----
| 270474929 || 2009-02-13T16:59:29Z || 198.103.96.11 || <nowiki>/* Operational history */</nowiki>
|----
| 270434425 || 2009-02-13T13:15:15Z || 76.66.196.229 || <nowiki>/* External links */</nowiki>
|----
| 270434385 || 2009-02-13T13:15:01Z || 76.66.196.229 || <nowiki>/* External links */</nowiki>
|----
| 270129632 || 2009-02-12T01:29:04Z || ClueBot || <nowiki>Reverting possible vandalism by [[Special:Contributions/173.24.222.13|173.24.222.13]] to version by Algkalv. False positive? [[User:ClueBot/FalsePositives|Report it]]. Thanks, [[User:ClueBot|ClueBot]]. (583887) (Bot)</nowiki>
|----
| 270129619 || 2009-02-12T01:28:59Z || 173.24.222.13 || <nowiki></nowiki>
|----
| 267556999 || 2009-01-31T05:33:55Z || Algkalv || <nowiki>/* Other civilian operators */ fix Stanley link</nowiki>
|----
| 263075642 || 2009-01-09T23:48:10Z || 99.247.62.105 || <nowiki>/* Airline operators */</nowiki>
|----
| 255597632 || 2008-12-03T08:23:48Z || TechBot || <nowiki>robot Modifying: [[fr:De Havilland Canada Dash 7]]</nowiki>
|----
| 255292030 || 2008-12-01T22:17:08Z || AnomieBOT || <nowiki>Replacing with per [[Wikipedia:Bot requests#Template substitution|request]]</nowiki>
|----
| 253129298 || 2008-11-21T04:29:10Z || M.nelson || <nowiki>/* Operational history */ Paragraph 2: wikilinked [[Rocky Mountain Airways]]</nowiki>
|----
| 253129237 || 2008-11-21T04:28:33Z || M.nelson || <nowiki>/* Other civilian operators */ changed "Dash-7" to "Dash 7" per article title</nowiki>
|----
| 253128408 || 2008-11-21T04:21:25Z || M.nelson || <nowiki>Intro: minor grammar fix</nowiki>
|----
| 247542795 || 2008-10-25T07:03:45Z || 216.108.162.141 || <nowiki>/* Airline operators */</nowiki>
|----
| 247542554 || 2008-10-25T07:00:34Z || 216.108.162.141 || <nowiki>/* Airline operators */</nowiki>
|----
| 245903378 || 2008-10-17T14:58:58Z || 199.198.251.100 || <nowiki></nowiki>
|----
| 242827517 || 2008-10-03T20:52:46Z || 79.74.120.85 || <nowiki>/* Other civilian operators */</nowiki>
|----
| 241437577 || 2008-09-28T00:51:29Z || 190.177.142.149 || <nowiki>/* Other civilian operators */</nowiki>
|----
| 241134645 || 2008-09-26T14:45:34Z || 207.236.147.118 || <nowiki>/* Design and development */ correcting a link</nowiki>
|----
| 241134546 || 2008-09-26T14:44:59Z || 207.236.147.118 || <nowiki>/* Design and development */ improving spelling</nowiki>
|----
| 237957017 || 2008-09-12T16:10:20Z || Tobibln || <nowiki>/* Airline operators */</nowiki>
|----
| 237956681 || 2008-09-12T16:08:18Z || Tobibln || <nowiki>/* Airline operators */</nowiki>
|----
| 237955237 || 2008-09-12T16:00:44Z || Tobibln || <nowiki>/* Airline operators */</nowiki>
|----
| 237954033 || 2008-09-12T15:53:56Z || Tobibln || <nowiki>/* Airline operators */</nowiki>
|----
| 237914189 || 2008-09-12T11:29:53Z || 79.178.102.31 || <nowiki>/* Airline operators */</nowiki>
|----
| 234584035 || 2008-08-27T15:35:30Z || Qui1che || <nowiki>/* References */ Added cite book template</nowiki>
|----
| 234583352 || 2008-08-27T15:31:46Z || Qui1che || <nowiki>/* Operational history */ Corrected spelling; added cite web template</nowiki>
|----
| 231892724 || 2008-08-14T12:38:06Z || 155.56.68.221 || <nowiki>/* Other civilian operators */ image on commons</nowiki>
|----
| 230772297 || 2008-08-09T08:11:37Z || Perceptive || <nowiki>/* Other civilian operators */ corrected link to Sky Blu</nowiki>
|----
| 229652417 || 2008-08-03T21:37:38Z || A300st || <nowiki>/* Operational history */</nowiki>
|----
| 229651974 || 2008-08-03T21:34:39Z || A300st || <nowiki>/* Operational history */</nowiki>
|----
| 229017766 || 2008-07-31T14:04:32Z || Lightbot || <nowiki>Units/dates/other</nowiki>
|----
| 227705148 || 2008-07-24T21:22:11Z || 79.178.240.28 || <nowiki>/* Airline operators */</nowiki>
|----
| 227705049 || 2008-07-24T21:21:38Z || 79.178.240.28 || <nowiki>/* Operators */</nowiki>
|----
| 224320546 || 2008-07-08T09:38:45Z || Delta 51 || <nowiki>+pl</nowiki>
|----
| 217290513 || 2008-06-05T12:07:38Z || Ahunt || <nowiki>removed non-notable and unsourced incident</nowiki>
|----
| 215798551 || 2008-05-29T19:32:38Z || Ahunt || <nowiki>adding category</nowiki>
|----
| 215634717 || 2008-05-29T01:20:58Z || 71.174.225.164 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 215634661 || 2008-05-29T01:20:38Z || 71.174.225.164 || <nowiki>/* Accidents and incidents */</nowiki>
|----
| 209847657 || 2008-05-03T04:59:34Z || 201.240.200.165 || <nowiki>/* Operational history */</nowiki>
|----
| 207853355 || 2008-04-24T13:35:56Z || Joshualam || <nowiki>/* Specifications */</nowiki>
|----
| 207853255 || 2008-04-24T13:35:31Z || Joshualam || <nowiki>/* Specifications */</nowiki>
|----
| 202050092 || 2008-03-30T13:57:05Z || 200.62.17.130 || <nowiki></nowiki>
|----
| 200154527 || 2008-03-22T21:28:07Z || 190.74.78.79 || <nowiki>/* Airline operators */</nowiki>
|----
| 197021160 || 2008-03-09T16:17:20Z || Bzuk || <nowiki>revert minor vandalism</nowiki>
|----
| 197014208 || 2008-03-09T15:38:54Z || 90.206.199.241 || <nowiki>/* Design and development */</nowiki>
|----
| 196430596 || 2008-03-07T01:27:24Z || Nimbus227 || <nowiki>Move 'see also' above references per [[WP:AIR/PC]] and [[WP:MOS]] , Manufacturer navbox first per WP:AIR</nowiki>
|----
| 196350473 || 2008-03-06T19:37:29Z || 199.209.255.227 || <nowiki>/* Airline operators */</nowiki>
|----
| 183447989 || 2008-01-10T18:41:49Z || MilborneOne || <nowiki>add template</nowiki>
|----
| 183070532 || 2008-01-09T00:11:47Z || GimmeBot || <nowiki>GimmeBot updating [[:Template:Aviation lists]] per [[WT:AIR]]</nowiki>
|----
| 181588638 || 2008-01-02T12:13:43Z || PixelBot || <nowiki>robot Modifying: [[ja:デハビランド・カナダ DHC-7]]</nowiki>
|----
| 181428115 || 2008-01-01T19:26:37Z || Bzuk || <nowiki>tweak format</nowiki>
|----
| 181418687 || 2008-01-01T18:29:15Z || Chris j wood || <nowiki>/* Other civilian operators */</nowiki>
|----
| 181232668 || 2007-12-31T18:32:42Z || Chris j wood || <nowiki>/* Airline operators */ You cannot operate a smaller number than one</nowiki>
|----
| 181232231 || 2007-12-31T18:30:26Z || Chris j wood || <nowiki>/* Operators */</nowiki>
|----
| 180471000 || 2007-12-27T19:31:08Z || MilborneOne || <nowiki>removed cat</nowiki>
|----
| 180466924 || 2007-12-27T19:08:11Z || Raymondwinn || <nowiki>add categories</nowiki>
|----
| 175782916 || 2007-12-04T21:06:58Z || 200.68.53.130 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 175782787 || 2007-12-04T21:06:18Z || 200.68.53.130 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 175477719 || 2007-12-03T13:22:55Z || SmackBot || <nowiki>Date/fix the maintenance tags or gen fixes using [[Project:AutoWikiBrowser|AWB]]</nowiki>
|----
| 175183770 || 2007-12-02T02:37:47Z || BilCat || <nowiki>Added {{fact}} tags</nowiki>
|----
| 175183504 || 2007-12-02T02:36:03Z || BilCat || <nowiki>Copy edits</nowiki>
|----
| 175170619 || 2007-12-02T01:16:48Z || BilCat || <nowiki>Reformatted sections</nowiki>
|----
| 175169766 || 2007-12-02T01:11:57Z || BilCat || <nowiki>/* Related content */ Added sequences</nowiki>
|----
| 173687809 || 2007-11-25T15:06:11Z || SmackBot || <nowiki>Date/fix the maintenance tags or gen fixes using [[Project:AutoWikiBrowser|AWB]]</nowiki>
|----
| 173062762 || 2007-11-22T07:11:36Z || Ng.j || <nowiki>[[Canadian Forces]]</nowiki>
|----
| 172912226 || 2007-11-21T14:38:42Z || Bzuk || <nowiki>probably accurate but needs attribution</nowiki>
|----
| 172911519 || 2007-11-21T14:33:34Z || 77.242.18.84 || <nowiki>/* Design and development */</nowiki>
|----
| 161675150 || 2007-10-01T23:29:09Z || 68.160.213.122 || <nowiki>Avianca never operated dash 7 /* Civilian Operators */</nowiki>
|----
| 159795005 || 2007-09-23T13:33:13Z || 82.81.217.136 || <nowiki>/* Related content */</nowiki>
|----
| 159513172 || 2007-09-22T01:22:05Z || Autonerd || <nowiki>Corrected: Main gear retract forward, not rearward. Reference: http://www.airliners.net/open.file/0643959/M/</nowiki>
|----
| 159253769 || 2007-09-20T21:24:53Z || John || <nowiki>Reverted edits by [[Special:Contributions/64.216.155.140|64.216.155.140]] ([[User talk:64.216.155.140|talk]]) to last version by 199.209.255.227</nowiki>
|----
| 159236058 || 2007-09-20T20:00:04Z || 64.216.155.140 || <nowiki>/* External links */</nowiki>
|----
| 159235860 || 2007-09-20T19:58:59Z || 64.216.155.140 || <nowiki>/* External links */</nowiki>
|----
| 158970444 || 2007-09-19T15:57:18Z || 199.209.255.227 || <nowiki>/* Military Operators */</nowiki>
|----
| 158970288 || 2007-09-19T15:56:28Z || 199.209.255.227 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 158969614 || 2007-09-19T15:52:44Z || 199.209.255.227 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 158375690 || 2007-09-16T23:03:24Z || 190.90.109.166 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 158178865 || 2007-09-16T02:00:41Z || 71.108.80.39 || <nowiki>/* Operational history */ ARL image</nowiki>
|----
| 157598090 || 2007-09-13T12:25:06Z || Nickybutt || <nowiki>/* Operational history */ +wikilink</nowiki>
|----
| 152163927 || 2007-08-19T02:36:00Z || 220.25.192.21 || <nowiki>/* Related content */</nowiki>
|----
| 152163815 || 2007-08-19T02:35:22Z || 220.25.192.21 || <nowiki>/* Related content */</nowiki>
|----
| 147708057 || 2007-07-28T19:09:14Z || Archtransit || <nowiki>typo</nowiki>
|----
| 147707640 || 2007-07-28T19:06:30Z || Archtransit || <nowiki>/* Operational history */ mentioned London City Airport</nowiki>
|----
| 146712620 || 2007-07-24T06:59:06Z || 212.143.124.165 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 146712108 || 2007-07-24T06:54:51Z || 212.143.124.165 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 138472322 || 2007-06-16T01:47:00Z || Bzuk || <nowiki>Probably just an aberration but the company never really used the designation DHC-7 or DHC-8 because they wanted to "rebadge" their products</nowiki>
|----
| 138463459 || 2007-06-16T00:43:38Z || BilCat || <nowiki>Various edits</nowiki>
|----
| 134482751 || 2007-05-30T03:25:48Z || Bzuk || <nowiki>revert deletion aithout explanation by anonyn</nowiki>
|----
| 134355904 || 2007-05-29T17:19:58Z || 216.113.24.1 || <nowiki></nowiki>
|----
| 128277582 || 2007-05-04T19:46:19Z || Bzuk || <nowiki>Removed flag icons as per [[WP:FLAGCRUFT]]</nowiki>
|----
| 128245363 || 2007-05-04T17:09:19Z || 206.47.220.230 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 128245231 || 2007-05-04T17:08:40Z || 206.47.220.230 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 128245142 || 2007-05-04T17:08:19Z || 206.47.220.230 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 128245076 || 2007-05-04T17:07:57Z || 206.47.220.230 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 128244923 || 2007-05-04T17:07:13Z || 206.47.220.230 || <nowiki>/* Civilian Operators */</nowiki>
|----
| 124759444 || 2007-04-22T01:38:40Z || Bzuk || <nowiki>/* References */ tweak reference- use MLA format</nowiki>
|----
| 124659027 || 2007-04-21T18:50:22Z || 24.108.186.67 || <nowiki>/* Civilian Operators */ m</nowiki>
|----
| 122908688 || 2007-04-15T03:49:16Z || Bzuk || <nowiki>/* Civilian Operators */ corrected information</nowiki>
|----
| 121248568 || 2007-04-08T19:47:28Z || Bzuk || <nowiki>/* Design and development */ revert vandalism</nowiki>
|----
| 121246981 || 2007-04-08T19:39:50Z || 202.133.178.88 || <nowiki></nowiki>
|----
| 120047179 || 2007-04-03T19:37:32Z || 160.39.195.112 || <nowiki>/* Design and development */</nowiki>
|----
| 117854486 || 2007-03-25T22:31:46Z || 198.53.251.83 || <nowiki>/* Design and development */</nowiki>
|----
| 106188127 || 2007-02-07T00:11:03Z || Merrittparkway || <nowiki>/* Design and development */Clarified reverse thrust. Turboprop, turbofan and turbojet engines cannot be "reversed."</nowiki>
|----
| 103594355 || 2007-01-27T12:37:39Z || Bzuk || <nowiki>Dates, typos</nowiki>
|----
| 103593352 || 2007-01-27T12:28:44Z || Bzuk || <nowiki>Another stupid bot</nowiki>
|----
| 103579466 || 2007-01-27T10:08:13Z || Escarbot || <nowiki>robot Modifying: [[no:De Havilland Canada DHC-7]]</nowiki>
|----
| 97139502 || 2006-12-29T14:43:47Z || Bzuk || <nowiki>/* Design and development */ tweaking</nowiki>
|----
| 97105827 || 2006-12-29T08:51:38Z || Dulciana || <nowiki>/* Design and development */ sp. 'ailerons'</nowiki>
|----
| 96667013 || 2006-12-27T02:59:46Z || Bzuk || <nowiki>/* Civilian Operators */ alphabetical order</nowiki>
|----
| 96515294 || 2006-12-26T06:38:55Z || Bzuk || <nowiki>/* References */ Dickman- stop it!</nowiki>
|----
| 96468160 || 2006-12-25T23:38:21Z || Karl Dickman || <nowiki>infobox</nowiki>
|----
| 96467248 || 2006-12-25T23:29:57Z || Karl Dickman || <nowiki>updates and tweaks</nowiki>
|----
| 93809970 || 2006-12-12T13:58:08Z || Bzuk || <nowiki>/* Trivia */ date</nowiki>
|----
| 93809859 || 2006-12-12T13:57:21Z || Bzuk || <nowiki>Added Photograph</nowiki>
|----
| 93780004 || 2006-12-12T09:14:59Z || Reedy || <nowiki>[[WP:AWB/T|Typo fixing]] Typos: March 27th → March 27 (2), using [[Project:AWB|AWB]]</nowiki>
|----
| 91595049 || 2006-12-02T14:44:42Z || Bzuk || <nowiki>/* Design and development */ twiddling</nowiki>
|----
| 91337636 || 2006-12-01T07:54:33Z || Charlene.fic || <nowiki></nowiki>
|----
| 90448410 || 2006-11-27T15:47:24Z || Bzuk || <nowiki>de Havilland Canada will be redirected to De Havilland Canada which is the default listing</nowiki>
|----
| 90442841 || 2006-11-27T15:14:45Z || Chrislk02 || <nowiki>/* Related content */ nav template</nowiki>
|----
| 82667566 || 2006-10-20T18:25:54Z || Bzuk || <nowiki>/* Incidents and accidents */ number system</nowiki>
|----
| 82649402 || 2006-10-20T16:37:54Z || Oden || <nowiki>/* End of the line */ Incidents and accidents</nowiki>
|----
| 82647545 || 2006-10-20T16:25:52Z || Oden || <nowiki>lowercase title</nowiki>
|----
| 81598551 || 2006-10-15T14:40:00Z || Bzuk || <nowiki>correction</nowiki>
|----
| 81593442 || 2006-10-15T14:03:39Z || Ardfern || <nowiki>/* Civilian Operators */</nowiki>
|----
| 80377019 || 2006-10-09T07:55:03Z || Bzuk || <nowiki>Clean-up, commas and the like</nowiki>
|----
| 80238259 || 2006-10-08T17:07:22Z || Ardfern || <nowiki>Aircraft in service added</nowiki>
|----
| 79887303 || 2006-10-06T18:22:37Z || Bzuk || <nowiki>sprucing up</nowiki>
|----
| 79745836 || 2006-10-05T23:33:59Z || Akradecki || <nowiki>bolding</nowiki>
|----
| 79745772 || 2006-10-05T23:33:37Z || Akradecki || <nowiki>ARL program</nowiki>
|----
| 79254174 || 2006-10-03T14:46:12Z || Bzuk || <nowiki>consistency in names, added reference</nowiki>
|----
| 73705720 || 2006-09-04T05:43:38Z || 153.111.60.15 || <nowiki></nowiki>
|----
| 65212277 || 2006-07-22T14:33:02Z || GangstaEB || <nowiki>/* Related content */ cat</nowiki>
|----
| 60715848 || 2006-06-26T20:17:36Z || Vonvon || <nowiki>Interwiki +fr</nowiki>
|----
| 51983200 || 2006-05-07T14:28:47Z || AzaBot || <nowiki>Robot: Changing template: Airtemp</nowiki>
|----
| 49647147 || 2006-04-22T20:49:35Z || Nick Moss || <nowiki></nowiki>
|----
| 47998756 || 2006-04-11T19:28:36Z || Scaife || <nowiki>/* Other references */ ...</nowiki>
|----
| 47998621 || 2006-04-11T19:27:47Z || Scaife || <nowiki>+ Ref</nowiki>
|----
| 46793308 || 2006-04-03T19:13:29Z || 157.127.124.141 || <nowiki>/* Military Operators */</nowiki>
|----
| 45206307 || 2006-03-24T02:56:48Z || Shenme || <nowiki>Spelling "asymetric" -> "asymmetric", "reveresed" -> "reversed", "it's" -> "its"</nowiki>
|----
| 44629038 || 2006-03-20T07:41:50Z || Emt147 || <nowiki>Migration to specs and related contents templates per [[Wikipedia:WikiProject Aircraft/page content]] using [[Wikipedia:AutoWikiBrowser|AWB]]</nowiki>
|----
| 43932693 || 2006-03-15T19:39:11Z || 83.130.232.135 || <nowiki></nowiki>
|----
| 42438731 || 2006-03-06T05:53:19Z || 153.111.60.15 || <nowiki></nowiki>
|----
| 42145802 || 2006-03-04T03:02:34Z || Alai || <nowiki>stub template fixing using [[Wikipedia:AutoWikiBrowser|AWB]]</nowiki>
|----
| 41367599 || 2006-02-26T22:11:24Z || Ian Pitchford || <nowiki>[[WP:AWB|AWB assisted]] clean up</nowiki>
|----
| 41277502 || 2006-02-26T06:10:29Z || Emt147 || <nowiki>clean up using [[Wikipedia:AutoWikiBrowser|AWB]]</nowiki>
|----
| 40055693 || 2006-02-17T20:33:44Z || Karl Dickman || <nowiki>/* Related content */ update aircontent</nowiki>
|----
| 38458330 || 2006-02-06T13:17:09Z || Maury Markowitz || <nowiki></nowiki>
|----
| 38457603 || 2006-02-06T13:08:06Z || Maury Markowitz || <nowiki>avoid redirect</nowiki>
|----
| 38457531 || 2006-02-06T13:07:08Z || Maury Markowitz || <nowiki></nowiki>
|----
| 38343436 || 2006-02-05T19:08:05Z || Maury Markowitz || <nowiki>cleanup</nowiki>
|----
| 38342596 || 2006-02-05T19:01:46Z || Maury Markowitz || <nowiki>sp</nowiki>
|----
| 38331113 || 2006-02-05T17:28:08Z || Maury Markowitz || <nowiki></nowiki>
|----
| 38330978 || 2006-02-05T17:26:54Z || Maury Markowitz || <nowiki>added refs</nowiki>
|----
| 38330706 || 2006-02-05T17:24:33Z || Maury Markowitz || <nowiki>rewrite</nowiki>
|----
| 34193947 || 2006-01-07T02:30:01Z || Change1211 || <nowiki></nowiki>
|----
| 32841464 || 2005-12-27T04:46:53Z || Ericg || <nowiki>/* Related content */ trim sequence - last/next three only</nowiki>
|----
| 25439351 || 2005-10-13T16:00:00Z || Trevor MacInnis || <nowiki>fix link</nowiki>
|----
| 25422650 || 2005-10-13T10:10:34Z || Sjakkalle || <nowiki>+no:</nowiki>
|----
| 25152038 || 2005-10-09T21:18:09Z || 212.99.193.28 || <nowiki></nowiki>
|----
| 24678233 || 2005-10-03T22:10:04Z || Sebastiankessel || <nowiki></nowiki>
|----
| 20509869 || 2005-08-08T00:53:49Z || Gene Nygaard || <nowiki></nowiki>
|----
| 20130697 || 2005-08-02T18:44:55Z || Ericg || <nowiki>/* Related content */</nowiki>
|----
| 20010076 || 2005-07-31T23:01:49Z || Ericg || <nowiki>/* Related content */ slight update to template, reflecting that here</nowiki>
|----
| 19811721 || 2005-07-28T21:47:14Z || Ericg || <nowiki></nowiki>
|----
| 17204790 || 2005-04-24T21:35:20Z || Trevor MacInnis || <nowiki></nowiki>
|----
| 12764704 || 2005-04-24T21:34:42Z || Trevor MacInnis || <nowiki>added table</nowiki>
|----
| 12764674 || 2005-02-17T11:35:35Z || William M. Connolley || <nowiki>It may be out of production but it still exists and its still flown. It should be spoken of in the present tense.</nowiki>
|----
| 10353544 || 2005-02-17T00:58:25Z || Rlandmann || <nowiki>...but has been out of production for over 15 years.</nowiki>
|----
| 10340657 || 2005-02-16T17:35:04Z || William M. Connolley || <nowiki>It still exists!</nowiki>
|----
| 10328096 || 2005-02-16T10:11:12Z || Rlandmann || <nowiki></nowiki>
|----
| 10319415 || 2005-02-15T22:57:17Z || Remuel || <nowiki>sorted stub</nowiki>
|----
| 10303524 || 2005-02-15T22:20:31Z || Tom L-C || <nowiki>Create as stub to hold piccy</nowiki>
|}
lpif8k53ir6sslskaqg0ig42jyhmvhy
User:Nardog/sandbox2.js
2
118608
735815
735651
2026-04-01T11:19:34Z
Nardog
40946
735815
javascript
text/javascript
(async function listTools() {
let pageAction = mw.config.get('wgAction');
let isView = pageAction === 'view';
let isEdit = ['edit', 'submit'].includes(pageAction);
if (!isView && !isEdit) return;
let pageType = mw.config.get('wgCanonicalSpecialPageName') ||
mw.config.get('wgNamespaceNumber');
if (isView && !pageType && !mw.config.exists('wgRedirectedFrom') &&
!mw.config.get('wgIsRedirect') &&
!mw.config.get('wgPageName').includes('/')
) {
return;
}
await mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api',
'mediawiki.interface.helpers.styles'
]);
mw.loader.addStyleTag(`.listtools:not(#mw-content-subtitle .listtools) {
font-size: 85%;
}
.listtools, .listtools a {
font-weight: normal !important;
font-style: normal;
}
.mw-datatable .listtools {
display: block;
}
.listtools + .mw-whatlinkshere-tools,
#watchlist-edit-form .listtools ~ .mw-changeslist-links,
.mw-special-DisambiguationPageLinks .listtools + a {
display: none;
}`);
let messages = Object.assign({
watched: 'Added "$1" to your watchlist',
watchFail: `Couldn't watch "$1"`,
unwatchFail: `Couldn't unwatch "$1"`
}, window.listtoolsMessages);
let getMsg = (key, ...args) => (
Object.hasOwn(messages, key) ? mw.format(messages[key], ...args) : key
);
let notif;
let watchHandler = async function (e) {
e.preventDefault();
let $link = $(this);
let $wrapper = $link.parent();
$link.detach();
let params = new URLSearchParams(this.search);
let action = params.get('action');
$wrapper.text(getMsg(action + 'ing'));
let pn = params.get('title').replaceAll('_', ' ');
let promise = new mw.Api()[action](pn);
if (notif) {
notif.close();
notif = null;
}
try {
let result = await promise;
if (!result || !result[action + 'ed']) throw '';
let newAction = action === 'watch' ? 'unwatch' : 'watch';
params.set('action', newAction);
$link.add(`.listtools-watch > a[href="${this.pathname + this.search}"]`)
.attr('href', this.pathname + '?' + params)
.text(getMsg(newAction));
if (action !== 'watch') return;
let require = await mw.loader.using([
'mediawiki.notification', 'mediawiki.watchstar.widgets'
]);
notif = await mw.notify(
new (require('mediawiki.watchstar.widgets'))('watch', pn, null, $.noop, {
message: getMsg('watched', pn)
}).$element,
{ tag: 'listtools' }
);
} catch {
notif = await mw.notify(getMsg(action + 'Fail', pn), {
tag: 'listtools',
type: 'error'
});
} finally {
$wrapper.html($link);
}
};
let extGetMain = function () {
return this.title;
};
let re = new RegExp(`(?:\\?title=|${
mw.util.escapeRegExp(mw.format(mw.config.get('wgArticlePath'), ''))
})([^#&?]+)`);
let processed = new WeakSet();
let processLinks = ($links, module, titles) => {
let isBatch = !!titles;
titles = titles || new Set();
$links.each(function (i) {
if (processed.has(this)) return;
let $link = $links.eq(i);
let pn;
if (module.useText) {
pn = $link.text();
} else {
let match = $link.attr('href')?.match(re);
if (!match) return;
pn = decodeURIComponent(match[1]);
}
let t = mw.Title.newFromText(pn);
if (!t) return;
if (module.titlesOnly) {
let text = $link.text();
if (text !== pn.replaceAll('_', ' ') &&
(text !== t.getMainText() || t.namespace === 2)
) {
return;
}
}
if ($link.is('.external, .extiw')) {
Object.assign(t, {
getMain: extGetMain,
host: this.host,
namespace: 0,
title: pn
});
} else {
if (t.namespace < 0) return;
if ($link.hasClass('new')) {
t.missing = true;
}
titles.add(t.getSubjectPage().toText());
}
let $tools = $('<span>').addClass('listtools mw-changeslist-links')
.data('listtools', t);
tools.forEach(tool => {
addTool($tools, tool);
});
if ($link.is(':is(del, bdi) > :only-child')) {
if (module.position === 'end') {
$link.parent().parent().append(' ', $tools);
} else {
$link.parent().after(' ', $tools);
}
} else if (module.position === 'end') {
$link.parent().append(' ', $tools);
} else {
$link.after(' ', $tools);
}
if (module.post) {
module.post($tools);
}
processed.add(this);
});
if (!isBatch) {
getWatched(titles);
}
};
let tools = [
{
name: 'edit',
url: t => t.getUrl({ action: 'edit' })
},
{
name: 'hist',
url: t => !t.missing && t.getUrl({ action: 'history' })
},
{
name: 'links',
url: t => mw.util.getUrl('Special:WhatLinksHere/' + t)
},
{
name: 'watch',
url: t => !t.host && t.getSubjectPage().getUrl({ action: 'watch' }),
callback: watchHandler
}
];
let addTool = ($tools, tool, escapedName) => {
let t = $tools.data('listtools');
let $duplicate = escapedName &&
$tools.children('.listtools-' + escapedName);
let url = tool.url;
if (typeof url === 'function') {
url = url(t);
if (!url) {
$duplicate?.remove();
return;
}
}
let $link = $('<a>').attr('href', url).text(getMsg(tool.name));
if (t.host) {
$link.prop('host', t.host);
}
if (tool.callback) {
$link.on('click', tool.callback);
}
let $wrapper = $('<span>').addClass('listtools-' + tool.name)
.append($link);
let $next = tool.next && $tools.children('.listtools-' + tool.next);
if ($next?.length) {
$duplicate?.remove();
$next.before($wrapper);
} else if ($duplicate?.length) {
$duplicate.replaceWith($wrapper);
} else {
$tools.append($wrapper);
}
};
let extend = tool => {
if (tool.label && !Object.hasOwn(messages, tool.label)) {
messages[tool.name] = tool.label;
}
if (tool.next) {
tool.next = $.escapeSelector(tool.next);
}
let existingTool = tools.find(t => t.name === tool.name);
if (existingTool) {
Object.assign(existingTool, tool);
} else {
tools.push(tool);
}
let escapedName = existingTool && $.escapeSelector(tool.name);
let $allTools = $('.listtools');
$allTools.each(function (i) {
addTool($allTools.eq(i), tool, escapedName);
});
};
let getWatched = async titles => {
if (!Array.isArray(titles)) {
titles = [...titles].slice(0, 500);
}
if (!titles.length) return;
(await new mw.Api().post({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages.forEach(page => {
if (!page.watched) return;
$(`.listtools-watch > a[href="${mw.util.getUrl(page.title, { action: 'watch' })}"]`)
.attr('href', mw.util.getUrl(page.title, { action: 'unwatch' }))
.text(getMsg('unwatch'));
});
getWatched(titles.slice(50));
};
mw.hook('listtools.ready').fire(extend);
let catTreeCallback = (records, observer) => {
let $links = $(records[0].target).find('.CategoryTreeItem > bdi > a');
if ($links.length) {
observer.takeRecords();
observer.disconnect();
processLinks($links, catTreeModule);
}
};
let catTreeModule = {
selector: '.CategoryTreeItem > bdi > a',
types: [14, 'CategoryTree'],
position: 'end',
post: $tools => {
$tools.parent().next('.CategoryTreeChildren').each(function () {
new MutationObserver(catTreeCallback)
.observe(this, { childList: true });
});
}
};
let modules = [
{
selector: '#mw-pages li > a, #mw-pages li > span > a',
types: [14]
},
catTreeModule,
{
selector: '#mw-imagepage-section-linkstoimage a, #mw-imagepage-section-globalusage a',
types: [6]
},
{
selector: '#mw-globalusage-result a',
types: ['GlobalUsage']
},
{
selector: '.mw-search-result-heading > a, .searchalttitle > a.mw-redirect, .iw-result__title > a, .mw-search-exists a',
types: ['Search']
},
{
selector: '.mw-search-createlink a',
types: ['Search'],
titlesOnly: true
},
{
selector: '#watchlist-edit-form .cdx-table td > label > a',
types: ['EditWatchlist']
},
{
selector: '.plainlinks > li > a',
types: ['AbuseLog'],
titlesOnly: true
},
{
selector: '#mw-allmessagestable td:first-child > a:first-child:not(.new)',
types: ['Allmessages'],
position: 'end'
},
{
selector: '.mw-spcontent li a',
types: ['DisambiguationPageLinks', 'Listredirects'],
titlesOnly: true
},
{
selector: 'li > a:first-child',
types: ['FileDuplicateSearch']
},
{
selector: '.TablePager_col_title > a:first-child, .TablePager_col_template > a',
types: ['LintErrors'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: 'form > ul > li > a',
types: ['Nuke'],
position: 'end',
titlesOnly: true
},
{
selector: '.page-assessments a',
types: ['PageAssessments'],
titlesOnly: true
},
{
selector: '.TablePager_col_pr_page > a',
types: ['Protectedpages'],
position: 'end'
},
{
selector: '#mw-content-text > ul a',
types: ['Protectedtitles'],
position: 'end'
},
{
selector: '.mw-fr-pending-changes-page-title',
types: ['PendingChanges'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: '#mw-content-text > ul a:first-child',
types: ['StablePages'],
position: 'end'
},
{
selector: '.TablePager_col__page a',
types: ['TopicSubscriptions']
},
{
selector: '.undeleteResult > a',
types: ['Undelete'],
position: 'end',
useText: true
},
{
selector: '.TablePager_col_img_name > a:first-child',
// types: ['Listfiles'],
position: 'end'
},
{
selector: '.mw-newpages-pagename',
post: $tools => {
let $contents = $tools.parent().contents();
$contents.slice(
$contents.index($tools) + 1,
$contents.index($contents.filter('.mw-newpages-length'))
).replaceWith(' ');
}
},
{
selector: '#mw-whatlinkshere-list li > bdi > a'
},
{
selector: '.mw-changeslist-log-entry > a:not(.mw-changeslist-log-gblblock a, .mw-changeslist-log-globalauth a)',
titlesOnly: true
},
{
selector: '.mw-logevent-loglines > li:not(.mw-logline-gblblock, .mw-logline-globalauth) > a',
types: ['Log'],
titlesOnly: true
},
{
selector: '#mw-diff-otitle1 > strong > a, #mw-diff-ntitle1 > strong > a',
types: ['ComparePages'],
position: 'end'
},
{
selector: '#movepage-oldlink, #movepage-newlink',
types: ['Movepage']
},
{
selector: '.mw-undelete-revision a:not(.mw-userlink, .mw-usertoollinks > a)',
types: ['Undelete'],
useText: true
},
{
selector: '.galleryfilename, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner-comment > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-enhanced-rc-nested > .comment > a'
},
{
selector: '.mw-spcontent li a',
position: 'end',
titlesOnly: true
}
];
if (isEdit) {
let post = $tools => {
if (!$tools[0].closest('.templatesUsed')) return;
$tools.parent().contents().last().each(function () {
this.textContent = this.textContent.slice(1);
}).end().slice(-3, -1).remove();
};
let callback = mw.util.debounce(() => {
processLinks(
$('.mw-editfooter-list a, #wikiPreview > .previewnote a'),
{ titlesOnly: true, post }
);
}, 500);
mw.hook('wikipage.editform').add($form => {
callback();
$form.find('.templatesUsed').each(function () {
if (processed.has(this)) return;
processed.add(this);
new MutationObserver(callback)
.observe(this, { childList: true, subtree: true });
});
});
} else if (typeof pageType === 'number') {
$(() => {
processLinks($('.subpages a, .mw-redirectedfrom a, .redirectText a'), {});
});
}
mw.hook('wikipage.content').add($content => {
let titles = new Set();
let $links = $content.find('a');
modules.forEach(module => {
if (module.types && !module.types.includes(pageType)) return;
processLinks($links.filter(module.selector), module, titles);
});
getWatched(titles);
});
}());
mw.hook('listtools.ready').add(extend => {
// extend({
// name: 'talk',
// url: t => !t.isTalkPage() && t.canHaveTalkPage() && t.getTalkPage().getUrl(),
// next: 'hist'
// });
extend({
name: 'subject',
url: t => t.isTalkPage() && t.getSubjectPage().getUrl(),
next: 'hist'
});
extend({
name: 'last',
url: t => !t.missing && t.getUrl({ diff: 'cur', diffonly: 1 }),
next: 'links'
});
// extend({
// name: 'purge',
// url: t => t.getUrl({ action: 'purge' }),
// next: 'watch',
// callback: function (e) {
// e.preventDefault();
// let $link = $(this);
// let $wrapper = $link.parent();
// $link.detach();
// $wrapper.text('purging');
// let pn = $wrapper.closest('.listtools').data('listtools').toText();
// new mw.Api().post({
// action: 'purge',
// forcelinkupdate: 1,
// titles: pn,
// formatversion: 2
// }).then(response => {
// if (response.purge[0].purged) {
// mw.notify(`Purged "${pn}"'`);
// }
// }).always(() => {
// $wrapper.html($link);
// });
// }
// });
extend({
name: 'copy',
url: '#',
callback: function (e) {
e.preventDefault();
let text = $(this).closest('.listtools').data('listtools').toText();
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch (err) {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
}
});
});
(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
mw.config.get('wgCanonicalSpecialPageName') !== 'GlobalContributions' &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector += ', ' + this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i + 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i + 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes += ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i + '/' + count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 + ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 + ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());
if (mw.config.get('wgNamespaceNumber') === 14 && (
mw.config.get('wgAction') === 'view' || !mw.config.get('wgArticleId')
)) {
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox8.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.DateFormatter',
'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget', 'mediawiki.widgets.datetime',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-movement',
'mediawiki.interface.helpers.styles', 'user.options'
]);
}
$(function moveHistory() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Move history', 't-movehistory').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.moveHistoryDialog) {
window.moveHistoryDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox5.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.Title', 'mediawiki.DateFormatter',
'oojs-ui-windows', 'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.DateInputWidget', 'oojs-ui.styles.icons-interactions',
'mediawiki.interface.helpers.styles'
]);
});
});
});
$(function sectionSearch() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Section search', 't-sectionsearch').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.sectionSearchDialog) {
window.sectionSearchDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox7.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-windows',
'mediawiki.widgets', 'mediawiki.widgets.NamespacesMultiselectWidget'
]);
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'CentralAuth' &&
mw.loader.using('jquery.tablesorter', function sortCentralAuthByEditCount() {
mw.hook('wikipage.content').add($content => {
let $table = $content.find('.mw-centralauth-wikislist').has('td');
if (!$table.length) return;
$table.tablesorter().data('tablesorter').sort([{ 4: 'desc' }, { 1: 'asc' }]);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
[10, 828].includes(mw.config.get('wgNamespaceNumber')) &&
!mw.config.get('wgTitle').endsWith('/doc') &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/AutoTestcases.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/TemplatePreviewGuard.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// $(function templatePreviewGuard() {
// let button = document.querySelector('input[name="wpTemplateSandboxPreview"]');
// if (!button) return;
// let proceed;
// button.addEventListener('click', e => {
// if (proceed) {
// proceed = false;
// return;
// }
// e.preventDefault();
// e.stopPropagation();
// let formData = new FormData(button.form);
// let page = formData.get('wpTemplateSandboxPage');
// let temp = formData.get('wpTemplateSandboxTemplate');
// if (!page || !temp) return;
// mw.loader.using('mediawiki.api').then(() => (
// new mw.Api().get({
// action: 'query',
// titles: page,
// prop: 'templates',
// tltemplates: temp,
// formatversion: 2
// })
// )).always(response => {
// if (((((response || {}).query || {}).pages || [])[0] || {}).templates ||
// confirm(`"${page}" doesn't appear to transclude "${temp}". Continue?`)
// ) {
// proceed = true;
// button.click();
// }
// });
// }, true);
// if (!mw.config.get('wgArticleId')) return;
// let widgetEl = document.querySelector('#wpTemplateSandboxPage.oo-ui-widget');
// if (!widgetEl) return;
// let pn = mw.config.get('wgPageName').replace(/_/g, ' ');
// mw.loader.using(['mediawiki.api', 'oojs-ui-core']).then(() => (
// new mw.Api().get({
// action: 'query',
// titles: pn,
// prop: 'transcludedin',
// tiprop: 'title',
// tilimit: 'max',
// formatversion: 2
// })
// )).then(response => {
// if (!response.batchcomplete) return;
// let pages = response.query.pages[0].transcludedin
// .filter(o => o.title !== pn);
// if (!pages.length) return;
// let widget = OO.ui.infuse(widgetEl);
// if (pages.length === 1) {
// widget.setValue(pages[0].title);
// return;
// }
// widget.$element.replaceWith(
// new OO.ui.ComboBoxInputWidget({
// id: 'wpTemplateSandboxPage',
// maxlength: widget.$input.prop('maxLength'),
// name: widget.$input.prop('name'),
// options: pages
// .sort((a, b) => a.ns - b.ns || -(a.title < b.title))
// .map(o => ({ data: o.title })),
// placeholder: widget.$input.prop('placeholder'),
// tabIndex: widget.getTabIndex(),
// value: widget.getValue()
// }).on('enter', e => {
// e.preventDefault();
// button.click();
// }).$element
// );
// });
// });
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(async () => {
let form = document.getElementById('editform');
if (!form) return;
let formData = new FormData(form);
let section = formData.get('wpSection');
if (section === 'new') return;
let widget = document.getElementById('wpSummaryWidget');
if (!widget) return;
let isOld = formData.get('altBaseRevId') > 0 ||
(formData.get('baseRevId') || formData.get('parentRevId')) !== formData.get('editRevId');
await mw.loader.using([
'jquery.textSelection', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core',
'oojs-ui.styles.icons-editing-core'
]);
let $textarea = $('#wpTextbox1');
let input = OO.ui.infuse(widget);
let button = new OO.ui.ButtonWidget({
framed: false,
icon: 'undo',
classes: ['autosectionlink-button'],
invisibleLabel: true,
label: 'Restore previous section link'
}).toggle().on('click', () => {
let cache = button.getData();
input.setValue(input.getValue().replace(
/^(\/\*.*?\*\/)?\s*/,
cache[0] ? '/* ' + cache[0] + ' */ ' : ''
));
updatePreview(cache[0]);
cache.reverse();
}).on('toggle', () => {
input.$input.css('width', `calc(100% - ${button.$element.width()}px)`);
});
input.$input.after(button.$element);
let update = mw.util.debounce($diff => {
let lines = $textarea.textSelection('getContents').replace(/\s+$/, '').split('\n');
let firstLineNum;
if (isOld) {
let i, lastLineNum;
$diff.find('td:last-child').each(function () {
if (this.classList.contains('diff-lineno')) {
i = this.textContent.replace(/\D+/g, '') - 1;
} else if (this.classList.contains('diff-context')) {
i++;
} else if (this.classList.contains('diff-addedline')) {
i++;
if (!firstLineNum) {
firstLineNum = i;
}
lastLineNum = i;
} else if (this.classList.contains('diff-empty')) {
if (!firstLineNum) {
firstLineNum = i === 0 ? 1 : i;
}
lastLineNum = i;
}
});
lines.length = lastLineNum || 0;
} else {
let origLines = $textarea.prop('defaultValue').replace(/\s+$/, '').split('\n');
firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
if (!firstLineNum) {
firstLineNum = lines.length < origLines.length
? lines.length
: 1;
}
for (let i = 1, x = lines.length, y = origLines.length;
(section ? i < x : i <= x) && lines[x - i] === origLines[y - i];
i++
) {
lines.pop();
}
}
let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 7;
lines.slice(firstLineNum).forEach(line => {
let match = line.match(re);
if (match && match[1].length < lowest) {
lowest = match[1].length;
}
});
let head;
lines.slice(0, firstLineNum).reverse().some(line => {
let match = line.match(re);
if (match && match[1].length < lowest) {
head = match[2];
return true;
}
});
if (head) {
head = head
.replace(/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
.replace(/''(.+?)''/g, '$1')
.trim();
}
let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
let prev = match[1];
if (typeof section === 'number' && section < 1 && lowest === 7 && !head) {
head = '';
}
if (prev === head) return;
input.setValue((typeof head === 'string' ? '/* ' + head + ' */ ' : '') + match[2]);
button.setData([prev, head]).toggle(true);
updatePreview(head);
}, 500);
let updatePreview = head => {
let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
if (!$preview.length) return;
let hasHead = typeof head === 'string';
let url = hasHead && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
let text = hasHead && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + (head || mw.messages.get('autocomment-top', '(top)'));
let $ac = $preview.children('.autocomment:first-child');
if ($ac.length && !$ac[0].previousSibling) {
if (hasHead) {
$ac.children('a').attr('href', url).text(text);
} else {
let node = $ac[0].nextSibling;
if (node?.nodeType === 3) {
node.textContent = node.textContent.replace(/^\s+/, '');
}
$ac.remove();
}
} else if (hasHead) {
$('<span>').addClass('autocomment').append(
$('<a>').attr({
href: url,
title: mw.config.get('wgPageName').replace(/_/g, ' ')
}).text(text),
mw.messages.get('colon-separator', ': ')
).prependTo($preview);
}
};
if (isOld) {
mw.hook('wikipage.diff').add(update);
} else {
$textarea.on('input', update);
mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
if (on && $codeMirror[0].CodeMirror) {
$codeMirror[0].CodeMirror.on('change', update);
}
});
mw.hook('ext.CodeMirror.input').add(update);
update();
}
new mw.Api().loadMessagesIfMissing(['autocomment-top', 'colon-separator']);
mw.loader.addStyleTag('.autosectionlink-button{position:absolute;top:0;right:0;margin:0}');
});
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(function copyRevId() {
let handler = function (e) {
e.preventDefault();
let text = this.closest('.diff td')?.querySelector('[data-mw-revid]')?.dataset.mwRevid ||
this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!text) return;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
document.execCommand('copy');
$input.remove();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id')
)
);
});
}());
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(() => {
let handler = async function (e) {
e.preventDefault();
let td = this.closest('.diff td');
let rev = td
? td.querySelector('[data-mw-revid]')?.dataset.mwRevid
: this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!rev) {
mw.notify(`Couldn't get the revision.`, {
tag: 'markasunseen',
type: 'error'
});
return;
}
let pn = td
? new URLSearchParams([...td.querySelectorAll('a')].pop()?.search).get('title')
: mw.config.get('wgPageName');
if (!pn) return;
await mw.loader.using('mediawiki.api');
let result = (await new mw.Api().postWithEditToken({
action: 'setnotificationtimestamp',
[td ? 'newerthanrevid' : 'torevid']: rev,
titles: pn,
formatversion: 2
})).setnotificationtimestamp?.[0];
if (Object.hasOwn(result, 'notificationtimestamp')) {
mw.notify(`Marked revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'success'
});
} else if (result?.notwatched) {
mw.notify('This page is not on your watchlist.', {
tag: 'markasunseen',
type: 'warn'
});
} else {
mw.notify(`Couldn't mark revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'error'
});
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions after this one as unseen'
}).on('click', handler).text('unseen'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions since this one as unseen'
}).on('click', handler).text('unseen')
)
);
});
})();
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
((mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4) ||
(mw.config.get('wgWikiID') === 'metawiki' && mw.config.get('wgPageContentModel') === 'wikitext')) &&
mw.loader.using(['mediawiki.util', 'mediawiki.Title'], function copyUnsig() {
let handler = function (e) {
e.preventDefault();
let parent = this.closest('li, td');
let ts = parent.textContent.match(/\d\d:\d\d, \d\d? [A-Z][a-z]+ \d{4}/)?.[0];
if (!ts) return;
let user = parent.querySelector('.mw-userlink').textContent;
if (mw.util.isIPv6Address(user)) {
user = user.toUpperCase();
}
let temp = mw.util.isIPAddress(user) ? 'unsigned IP' : 'unsigned';
let text = `{{subst:${temp}|${user}|${ts}}}`;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').filter(function () {
if (mw.config.get('wgWikiID') === 'metawiki') {
return true;
}
let link = this.querySelector('strong > a') ||
this.parentElement.querySelector('#differences-prevlink, #differences-nextlink');
if (!link) return;
let t = mw.Title.newFromText(mw.util.getParamValue('title', link.search));
return t.isTalkPage() || t.namespace === 4;
}).append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig')
)
);
});
});
// mw.config.get('wgAction') === 'history' &&
// mw.loader.using('mediawiki.util', function () {
// mw.hook('wikipage.content').add($content => {
// $content.find('a.mw-changeslist-date').after(function () {
// return [
// ' (',
// $('<a>').attr('href', mw.util.getUrl(null, {
// action: 'edit',
// oldid: this.closest('li').dataset.mwRevid
// })).text('e'),
// ')'
// ];
// });
// });
// });
// ['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
// mw.hook('wikipage.content').add($content => {
// $content.find('.mw-changeslist-history').parent().after(function () {
// return $('<span>').append(
// $('<a>').attr(
// 'href',
// this.firstElementChild.getAttribute('href').slice(0, -7) + 'edit'
// ).text('e')
// );
// });
// });
if (screen.width < 500) {
mw.loader.addStyleTag('@font-face{font-family:CharisW;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/017b2b2ad86e09d3c22b8cf0dfc78247/CharisSILRegular.ttf) format(truetype)} @font-face{font-family:CharisW;font-weight:700;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/6f5069ac6a300dad45383c952e92c573/CharisSILBold.ttf) format(truetype)} body .IPA{font-family:CharisW,sans-serif} .mw-highlight-lines > pre{width:120em}');
location.hash && $(() => {
let target = document.querySelector(':target');
if (target?.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
});
}
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
(mw.config.exists('wgCodeEditorCurrentLanguage') ||
mw.config.exists('cmMode') && mw.config.get('cmMode') !== 'mediawiki') &&
(function saveNEdit() {
let notif;
$(document.body).on('click', '#wpSave', async function (e) {
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey ||
e.originalEvent?.defaultPrevented
) {
return;
}
e.preventDefault();
await mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'jquery.textSelection', 'oojs-ui-core'
]);
let button = OO.ui.infuse(this.parentElement).setDisabled(true);
let $textarea = $('#wpTextbox1');
let text = $textarea.textSelection('getContents');
let $summary = $('#wpSummary');
let formData = new FormData(this.form);
let promise = new mw.Api().postWithEditToken({
action: 'edit',
title: mw.config.get('wgPageName'),
text: text,
section: formData.get('wpSection') || undefined,
summary: $summary.textSelection('getContents'),
[$('#wpMinoredit').prop('checked') ? 'minor' : 'notminor']: 1,
baserevid: formData.get('editRevId'),
basetimestamp: formData.get('wpEdittime'),
starttimestamp: formData.get('wpStarttime'),
watchlist: $('#wpWatchthis').prop('checked') ? 'watch' : 'unwatch',
watchlistexpiry: formData.get('wpWatchlistExpiry') || undefined,
undo: formData.get('wpUndidRevision') || undefined,
undoafter: formData.get('wpUndoAfter') || undefined,
contentformat: formData.get('format'),
contentmodel: formData.get('model'),
assertuser: mw.config.get('wgUserName'),
formatversion: 2
});
notif?.close();
notif = null;
try {
let response = await promise;
if (response?.edit?.result !== 'Success') throw '';
$('#editform > input[name="wpUndidRevision"], #editform > input[name="wpUndoAfter"]').remove();
$textarea.data('origtext', text).prop('defaultValue', text);
$summary.val($summary.prop('defaultValue'));
if (mw.loader.getState('mediawiki.editRecovery.edit') === 'ready') {
let storage = mw.loader.moduleRegistry['mediawiki.editRecovery.edit'].packageExports['storage.js'];
storage.deleteData(mw.config.get('wgPageName'));
storage.closeDatabase();
}
notif = await mw.notify(response.edit.nochange ? 'No change' : [
document.createTextNode('Saved'),
$('<p>').append(
new OO.ui.ButtonWidget({
href: mw.util.getUrl(),
target: '_blank',
label: 'View'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, {
diff: response.edit.newrevid || 'cur',
diffonly: 1
}),
target: '_blank',
label: 'Diff'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, { action: 'history' }),
target: '_blank',
label: 'History'
}).$element
)[0]
], { tag: 'savenedit' });
} catch (error) {
notif = await mw.notify(error?.error?.info || error || 'Save failed', {
autoHideSeconds: 'long',
tag: 'savenedit',
type: 'error'
});
} finally {
button.setDisabled();
}
});
}());
mw.config.get('wgNamespaceNumber') === 0 &&
mw.config.get('wgAction') === 'view' &&
mw.config.get('wgCategories')?.some(c => c.endsWith(' actors') || c.endsWith(' actresses')) &&
$(() => {
let n = $.escapeSelector(mw.config.get('wgTitle').replace(/ \(.+\)$/, ''));
let $links = $(`.hatnote a[title$="${n} filmography"], .hatnote a[title*="${n} on "], .hatnote a[title*="${n} performances"]`);
if (!$links.length) return;
let titles = {};
$links = $links.filter(function () {
let text = this.textContent;
return !(titles[text] = Object.hasOwn(titles, text));
});
mw.notify(
$links.length === 1
? $links.clone()
: $('<ul>').append($links.clone().wrap('<li>').parent()),
{ autoHideSeconds: 'long' }
);
});
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
let os = mw.user.options.get('userjs-rcmuter');
let set = new Set(os && os.split('|'));
let save = () => {
let ns = [...set].join('|');
if (ns === mw.user.options.get('userjs-rcmuter')) return;
new mw.Api().saveOption('userjs-rcmuter', ns);
mw.user.options.set('userjs-rcmuter', ns);
$edit.attr('data-rcmuter', set.size);
};
mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
let $edit = $('<a>').attr({
class: 'rcmuter-edit',
href: '#',
'data-rcmuter': set.size
}).text('Edit muted').on('click', e => {
e.preventDefault();
mw.loader.using([
'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
let multiselect = new mw.widgets.UsersMultiselectWidget({
$overlay: dialog.$overlay,
ipAllowed: true,
selected: [...set]
}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
let instance = dialog.open({
message: $([
document.createTextNode('Muted users:'),
multiselect.$element[0]
]),
size: 'medium'
});
instance.opened.then(() => {
setTimeout(() => {
multiselect.focus().menu.toggle(false);
});
});
instance.closed.then(result => {
if (!result || result.action !== 'accept') return;
set = new Set(multiselect.getSelectedUsernames());
save();
mw.notify('Changes will take effect in next load.', {
tag: 'rcmuter'
});
});
});
});
let buttonsShown;
let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
e.preventDefault();
if (buttonsShown) {
mw.hook('wikipage.content').remove(addButtons);
$('.rcmuter-toggle').remove();
this.textContent = 'Show toggle buttons';
} else {
mw.hook('wikipage.content').add(addButtons);
this.textContent = 'Hide toggle buttons';
}
buttonsShown = !buttonsShown;
});
let $toggle = $('<a>').attr({
class: 'rcmuter-togglemuted',
href: '#'
}).text('Show muted').on('click', function (e) {
e.preventDefault();
this.textContent = document.body.classList.toggle('rcmuter-disabled')
? 'Hide muted'
: 'Show muted';
});
let $toggleSpan = $('<span>').hide().append($toggle);
mw.util.addSubtitle(
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append($edit),
$('<span>').append($toggleButtons),
$toggleSpan
)[0]
);
let toggle = function (e) {
e.preventDefault();
let user = $(this)
.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
.last().text().trim();
if (!user) {
mw.notify(`Can't retrieve the username.`, {
tag: 'rcmuter',
type: 'error'
});
return;
}
let muting = this.parentElement.classList.toggle('rcmuter-unmute');
set[muting ? 'add' : 'delete'](user);
save();
this.textContent = muting ? 'unmute' : 'mute';
mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
tag: 'rcmuter'
});
};
let addButtons = $content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) {
$content = $('#mw-content-text');
if ($content.has('.rcmuter-toggle').length) return;
}
let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
let $muted = $tools.filter('.rcmuter-muted *');
$tools.not($muted).append(
$('<span>').addClass('rcmuter-toggle').append(
$('<a>').attr('href', '#').text('mute').on('click', toggle)
)
);
if (!$muted.length) return;
$muted.append(
$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
$('<a>').attr('href', '#').text('unmute').on('click', toggle)
)
);
};
let mutedCount;
let filter = function () {
let muted = set.has(this.textContent);
if (muted) mutedCount++;
return muted;
};
mw.hook('wikipage.content').add($content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) return;
if (!set.size) {
$toggleSpan.hide();
return;
}
mutedCount = 0;
$content.find('.changedby > .mw-userlink:only-child')
.filter(filter).closest('table').addClass('rcmuter-muted');
$content.find('.mw-userlink:not(.changedby > *, .comment *, .rcmuter-muted *)')
.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
$toggleSpan.toggle(!!mutedCount);
$toggle.attr('data-rcmuter', mutedCount);
});
});
location.hostname.endsWith('.wikipedia.org') &&
mw.config.get('wgNamespaceNumber') % 2 === 0 &&
// mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.util')).then(function refRenamer() {
if (!document.getElementById('p-tb')) return;
let messages = Object.assign({
portlet: 'RefRenamer',
loading: 'Loading RefRenamer...'
}, window.refrenamerMessages);
let clicked;
mw.util.addPortletLink('p-tb', '#', messages.portlet, 't-refrenamer').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.refRenamer) {
window.refRenamer();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox6.js&action=raw&ctype=text/javascript');
mw.notify(messages.loading, {
autoHideSeconds: 'long',
tag: 'refrenamer'
});
});
});
if (['edit', 'submit'].includes(mw.config.get('wgAction'))) {
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/ExpandContractions.js&action=raw&ctype=text/javascript', 's');
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/Unpipe.js&action=raw&ctype=text/javascript', 's');
}
mw.config.get('wgAction') !== 'history' &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/CopyCodeBlock.js&action=raw&ctype=text/javascript', 's');
mw.config.exists('wgDiffNewId') &&
mw.config.get('wgDiscussionToolsFeaturesEnabled') &&
(function () {
let data = {}, clickHandler, autoClear, run;
window.dtc = data;
let highlight = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
mw.loader.moduleRegistry['ext.discussionTools.init'].packageExports['highlighter.js']
.highlightNewComments(mw.dt.pageThreads, true, ids);
if (clickHandler) {
$(document.body).off('click', clickHandler);
return;
}
$._data(document.body, 'events').click.some(o => {
if (String(o.handler).includes('highlighter.clearHighlightTargetComment(')) {
$(document.body).off('click', o.handler);
clickHandler = o.handler;
return true;
}
});
$._data(window, 'events').popstate.some(o => {
if (String(o.handler).includes('highlighter.highlightTargetComment(')) {
$(window).off('popstate', o.handler);
return true;
}
});
};
let scroll = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
let yToSpan = Object.fromEntries(
ids.map(id => document.getElementById(id)).filter(Boolean)
.map(span => [span.getBoundingClientRect().y, span])
);
let ys = Object.keys(yToSpan);
if (!ys.length) return;
let lower = ys.filter(y => y > 10);
if (!lower.length ||
Math.max(...lower) < document.documentElement.clientHeight
) {
yToSpan[Math.min(...ys)].scrollIntoView();
} else {
yToSpan[Math.min(...lower)].scrollIntoView();
}
};
let scrollToNext = function (e) {
e.preventDefault();
let revId = mw.config.get('wgDiffOldId');
if (!revId || !data[revId]) return;
let i = data[revId].indexOf(
this.closest('[data-mw-thread-id]').dataset.mwThreadId
);
if (i === -1) return;
let next = data[revId][i + 1] || data[revId][0];
document.getElementById(next).scrollIntoView();
};
mw.hook('wikipage.content').add(async $content => {
let revId = mw.config.get('wgDiffOldId');
if (!revId) return;
let param = new URLSearchParams(location.search).get('diffonly');
if (param && param !== '0') return;
if (data[revId]) {
highlight(revId);
return;
}
await mw.loader.using(['ext.discussionTools.init', 'mediawiki.util']);
let begin = Date.parse($('#mw-diff-otitle1 .mw-diff-timestamp').data('timestamp'));
data[revId] = mw.dt.pageThreads.getCommentItems()
.filter(c => c.timestamp > begin).map(c => c.id);
if (!data[revId].length) return;
await new Promise(setTimeout);
highlight(revId);
$content.find('.ext-discussiontools-init-replylink-buttons').filter(function () {
return data[revId].includes(this.dataset.mwThreadId);
}).children('span:last-of-type').before(
' | ',
$('<a>').attr({
href: '#',
role: 'button'
}).text('next').on('click', scrollToNext)
);
if (run || !document.getElementById('p-tb')) return;
run = true;
let portlet = mw.util.addPortletLink('p-tb', '#', 'Scroll to next', 't-scrolltonext');
portlet.firstElementChild.addEventListener('click', e => {
e.preventDefault();
scroll(mw.config.get('wgDiffOldId'));
});
mw.util.addPortletLink('p-tb', '#', 'Toggle highlight', 't-togglehighlight').firstElementChild.addEventListener('click', e => {
e.preventDefault();
autoClear = !autoClear;
if (autoClear) {
$(document.body).on('click', clickHandler)[0].click();
} else {
highlight(mw.config.get('wgDiffOldId'));
}
});
mw.loader.addStyleTag(`#t-scrolltonext{position:fixed;bottom:${portlet.clientHeight}px} #t-togglehighlight{position:fixed;bottom:0}`);
});
}());
mw.config.get('wgNamespaceNumber') === 6 &&
mw.config.get('wgAction') === 'view' &&
mw.hook('wikipage.content').add($content => {
$content.find('.filehistory .mw-usertoollinks-contribs').after(function () {
return [
' | ',
$('<a>').attr('href', `${
mw.config.get('wgScript')
}?title=Special:ListFiles/${
this.pathname.replace(/^.+\//, '')
}&ilshowall=1`).text('uploads')
];
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function () {
if (!$('input[name="wpSection"]').val()) return;
mw.hook('wikipage.content').add(async $content => {
let $refs = $content.find('.mw-ext-cite-warning-sectionpreview_no_text');
if (!$refs.length) return;
let ids = {};
$refs.each(function () {
ids[this.closest('[id]').id.replace(/-\d+$/, '')] = this;
});
let response = await $.get(`/api/rest_v1/page/html/${encodeURIComponent(mw.config.get('wgPageName'))}`);
$($.parseHTML(response)).find('.mw-reference-text').each(function () {
ids[this.id.replace(/^mw-reference-text-|-\d+$/g, '')]?.replaceWith(this);
});
});
});
mw.hook('moremenu.ready').add(config => {
$('#mm-page-purge-cache > a').on('click', e => {
e.preventDefault();
new mw.Api().post({
action: 'purge',
forcelinkupdate: 1,
titles: config.page.name,
formatversion: 2
}).then(() => {
location.href = mw.util.getUrl();
});
});
$('#mm-page-search-search-history-wikiblame > a').on('click', function (e) {
e.preventDefault();
let q = prompt();
if (q === null) return;
let href = this.href;
if (q) {
let removal = q[0] === '!';
if (removal) {
q = q.slice(1);
}
href += '&needle=' + encodeURIComponent(q);
if (removal) {
href += '&binary_search_inverse=on';
}
href += '&force_wikitags=on';
}
open(href, '_blank');
});
$('#mm-page-expand-templates > a').on('click auxclick', function (e) {
if (e.which > 2) return;
e.preventDefault();
let revId = mw.config.get('wgRevisionId') || Number($('input[name=oldid]').val());
let url = revId
? '/w/rest.php/v1/revision/' + revId
: '/w/rest.php/v1/page/' + config.page.encodedName;
$.get(url).then(response => {
$('<form>').attr({
method: 'post',
action: this.href,
target: '_blank'
}).append(
[
['wpInput', response.source],
['wpContextTitle', config.page.name],
['wpRemoveComments', 1]
].map(([n, v]) => $('<input>').attr({
name: n,
type: 'hidden'
}).val(v))
).appendTo(document.body).trigger('submit').remove();
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'ApiSandbox' &&
mw.hook('apisandbox.formatRequest').add((...args) => {
args[4].complete = function () {
setTimeout(() => {
mw.hook('wikipage.content').fire($('.oo-ui-pageLayout-active'));
}, 100);
};
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.storage')).then(async () => {
let infuseAndCall = (query, method, ...args) => {
let $widget = $(query);
if ($widget.length) {
return OO.ui.infuse($widget)[method](...args);
}
};
let section = $('input[name="wpSection"]').val();
if (section) {
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let save = () => {
let newSource = $textarea.textSelection('getContents');
if (newSource === source) {
mw.storage.session.remove('editfullpage');
} else {
mw.storage.session.setObject('editfullpage', [
mw.config.get('wgPageName'),
section,
newSource.trimEnd(),
infuseAndCall('#wpSummaryWidget', 'getValue') || '',
Number(infuseAndCall('#wpMinoreditWidget', 'isSelected')) || 0,
Number(infuseAndCall('#wpWatchthisWidget', 'isSelected')) || 0,
infuseAndCall('#wpWatchlistExpiryWidget', 'getValue') || 'infinite'
]);
}
};
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
setInterval(() => {
mw.requestIdleCallback(save);
}, 3000);
window.addEventListener('beforeunload', save);
return;
}
let data = mw.storage.session.getObject('editfullpage');
mw.storage.session.remove('editfullpage');
console.log(data);
if (!data || data[0] !== mw.config.get('wgPageName')) return;
let isNew = data[1] === 'new';
let isLead = data[1] === '0';
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let newSource, start, msg, notifOpts = { autoHideSeconds: 'long' };
let orig = [];
if (isNew) {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
newSource = source + (data[3] ? '\n== ' + data[3] + ' ==\n\n' : '\n') + data[2] + '\n';
start = source.length;
} else {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core', 'mediawiki.api']);
let { parse } = await new mw.Api().get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
wrapoutputclass: '',
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
formatversion: 2
});
let target = !isLead && parse.sections.find(s => s.index === data[1]);
if (isLead || target) {
let next = parse.sections.find(s => s.index - 1 === Number(data[1]));
newSource = (isLead ? '' : [...source].slice(0, target.byteoffset)).join('') +
data[2] + (next ? '\n\n' + [...source].slice(next.byteoffset).join('') : '\n');
start = isLead ? 0 : target.byteoffset;
} else {
newSource = source + '\n\n' + data[2] + '\n';
start = source.length;
msg = `Section restored. Couldn't find the section. The source is appended at bottom.`;
notifOpts.type = 'warn';
}
orig[0] = infuseAndCall('#wpSummaryWidget', 'getValue');
infuseAndCall('#wpSummaryWidget', 'setValue', data[3]);
}
$textarea.textSelection('setContents', newSource);
orig[1] = infuseAndCall('#wpMinoreditWidget', 'getSelected');
infuseAndCall('#wpMinoreditWidget', 'setSelected', data[4]);
orig[2] = infuseAndCall('#wpWatchthisWidget', 'getSelected');
infuseAndCall('#wpWatchthisWidget', 'setSelected', data[5]);
orig[3] = infuseAndCall('#wpWatchlistExpiryWidget', 'getValue');
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', data[6]);
setTimeout(() => {
$textarea.textSelection('setSelection', { start });
});
let notif = await mw.notify($([
document.createTextNode(msg || 'Section restored.'),
$('<p>').append(
new OO.ui.ButtonWidget({
flags: 'destructive',
label: 'Discard'
}).on('click', () => {
$textarea.textSelection('setContents', source);
if (orig[0]) {
infuseAndCall('#wpSummaryWidget', 'setValue', orig[0]);
}
infuseAndCall('#wpMinoreditWidget', 'setSelected', orig[1]);
infuseAndCall('#wpWatchthisWidget', 'setSelected', orig[2]);
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', orig[3]);
notif.close();
}).$element
)[0]
]), notifOpts);
});
mw.config.exists('wgPostEdit') &&
mw.loader.using('mediawiki.storage', () => {
mw.storage.session.remove('editfullpage');
});
mw.config.get('wgAction') === 'history' &&
mw.hook('wikipage.content').add(async $content => {
if (!$content.has('.mw-history-line-updated').length) return;
let href = $content.find('a.mw-history-histlinks-current:not(.mw-history-line-updated a)').attr('href');
if (!href) {
await mw.loader.using(['mediawiki.api', 'mediawiki.util']);
let page = (await new mw.Api().get({
action: 'query',
titles: mw.config.get('wgPageName'),
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev >= page.lastrevid) return;
href = mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
}
$content.find('.mw-history-compareselectedversions-button').first().after(
' ',
$('<a>').attr({
class: 'unseendiff',
href: href
}).text('unseen')
);
});
(async () => {
let cspn = mw.config.get('wgCanonicalSpecialPageName');
let isBp = cspn === 'Blankpage';
if (!isBp && cspn !== 'Watchlist') return;
await mw.loader.using('mediawiki.util');
let notify = async (text, options, pn) => {
let msg = [document.createTextNode(text)];
if (pn) {
msg.push(
$('<p>').append(
$('<a>').attr('href', mw.util.getUrl(pn)).text(pn),
' ',
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'edit' }))
.text('edit')
),
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'history' }))
.text('history')
)
)
)[0]
);
}
if (isBp) {
await $.ready;
$('#mw-content-text').html(msg);
} else {
return mw.notify(msg, Object.assign(options || {}, {
tag: 'unseendiff'
}));
}
};
let getUrl = async pn => {
await mw.loader.using('mediawiki.api');
let page = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
if (!page.notificationtimestamp) {
notify(`Couldn't get the last seen time.`, {
type: 'warn'
}, pn);
return;
}
let rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (rev === page.lastrevid) {
notify('Already seen.', {
type: 'warn'
}, pn);
return;
}
if (!rev) {
rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
rvdir: 'newer',
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev) {
notify(`Couldn't get the last seen revision.`, {
type: 'warn'
}, pn);
return;
}
}
if (rev > page.lastrevid) {
notify(`Invalid rev for "${pn}" (rev: ${rev}, lastrevid: ${page.lastrevid})`, {
autoHideSeconds: 'long',
type: 'warn'
}, pn);
return;
}
return mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
};
if (isBp) {
let pn = mw.config.get('wgTitle').match(/^[^/]+\/unseendiff\/(.+)$/)?.[1];
if (!pn) return;
notify('Loading...', null, pn);
let href = await getUrl(pn);
if (!href) return;
notify('Redirecting...', null, pn);
location.href = href;
return;
}
let handler = async function (e) {
if (e.which > 2) return;
e.preventDefault();
let pn = this.dataset.pn;
if (!pn) {
notify(`Couldn't get the page name.`, {
type: 'error'
});
return;
}
let notifPromise = notify('Loading...', {
autoHideSeconds: 'long'
});
let href = await getUrl(pn);
if (!href) return;
$(`.unseendiff-loader[data-pn="${$.escapeSelector(pn)}"]`).attr({
class: 'unseendiff',
href: href,
target: '_blank'
}).off('click auxclick', handler);
if (e.type === 'auxclick' || e.ctrlKey || e.metaKey || e.shiftKey) {
open(href);
} else {
this.click();
}
(await notifPromise).close();
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-changeslist-src-mw-edit.mw-changeslist-watchedunseen:not(.mw-changeslist-watchedseen) .mw-changeslist-line-inner'
).each(function () {
let pn = this.dataset.targetPage ||
this.closest('[data-target-page]')?.dataset.targetPage ||
this.closest('table.mw-enhanced-rc')?.querySelector('[data-target-page]')?.dataset.targetPage;
if (!pn) return;
$('<span>').append(
$('<a>').attr({
class: 'unseendiff-loader',
href: mw.util.getUrl(`Special:BlankPage/unseendiff/${pn}`),
'data-pn': pn
}).on('click auxclick', handler).text('unseen')
).appendTo(
[...this.querySelectorAll('.mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
});
})();
['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
mw.loader.using('mediawiki.util', () => {
let watched = new Set();
let query = async lis => {
let titles = Object.keys(lis).slice(0, 50);
if (!titles.length) return;
await mw.loader.using('mediawiki.api');
let pages = (await new mw.Api().post({
action: 'query',
titles: titles,
prop: 'info',
inprop: 'notificationtimestamp|watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages;
for (let page of pages) {
if (!Object.hasOwn(lis, page.title)) continue;
if (page.watched) {
watched.add(page);
$(lis[page.title]).addClass('watched');
}
if (!page.notificationtimestamp) continue;
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev === page.lastrevid) continue;
if (rev > page.lastrevid) {
mw.notify($([
document.createTextNode('Invalid rev for "'),
$('<a>').attr({
href: mw.util.getUrl(page.title, { action: 'history' }),
target: '_blank'
}).text(page.title)[0],
document.createTextNode(`" (rev: ${rev}, lastrevid: ${page.lastrevid})`),
]), {
autoHideSeconds: 'long',
type: 'warn'
});
continue;
}
$('<span>').append(
$('<a>').attr({
class: 'unseendiff',
href: mw.util.getUrl(page.title, {
diff: page.lastrevid,
oldid: rev
})
}).text('unseen')
).appendTo(
lis[page.title].map(li => (
[...li.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(li).before(' ')
))
);
}
titles.forEach(title => {
delete lis[title];
});
query(lis);
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-contributions-list > li:not(.mw-contributions-current)[data-mw-revid]'
).each(function () {
let link = this.querySelector('a.mw-changeslist-date, a.mw-changeslist-history');
let pn = link ? new URLSearchParams(link.search).get('title') : '';
$('<span>').append(
$('<a>').attr({
class: 'mw-changeslist-diff',
href: mw.util.getUrl(pn, {
diff: 'cur',
oldid: this.dataset.mwRevid
})
}).text('cur')
).appendTo(
[...this.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
if (mw.config.get('wgWikiID') === 'wikidatawiki') return;
let lis = {};
$content.find('.mw-contributions-title').each(function () {
let title = this.textContent;
if (!Object.hasOwn(lis, title)) {
lis[title] = [];
}
lis[title].push(this.closest('li'));
});
Object.keys(lis).forEach(title => {
if (watched.has(title)) {
$(lis[title]).addClass('watched');
delete lis[title];
}
});
query(lis);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox9.js&action=raw&ctype=text/javascript');
mw.config.get('wgWikiID') === 'metawiki' &&
(async () => {
let css = mw.loader.addStyleTag(`.wishtitle {
font-size: 90%;
font-style: italic;
word-break: break-word;
}
.wishtitle > a {
color: var(--color-warning, #886425);
}
.wishtitle > a:visited {
color: var(--border-color-warning--hover, #735421);
}
.wishtitle-declined > a {
text-decoration: line-through;
}
.wishtitle-declined > a:hover,
.wishtitle-declined > a:focus,
.mw-underline-always .wishtitle-declined > a {
text-decoration: line-through underline;
}
#watchlist-edit-form .wishtitle {
display: inline-block;
}
.mw-search-result-heading > .wishtitle,
.catchangesviewer-table .wishtitle {
display: block;
}
.catchangesviewer-table:has(.wishtitle) {
white-space: wrap;
}`);
let lang = mw.config.get('wgUserLanguage');
let titles;
let loadTitles = async () => {
await mw.loader.using('mediawiki.storage');
titles = titles || mw.storage.getObject('wishtitles');
if (titles?.lang !== lang) {
titles = { lang, w: [], fa: [] };
}
};
let updateTitles = async (crwstatuses, crwcontinue) => {
await mw.loader.using('mediawiki.api');
let params = {
action: 'query',
list: 'communityrequests-wishes',
crwlang: lang,
crwstatuses: crwstatuses,
crwprop: 'title|updated',
crwsort: 'updated',
crwdir: 'ascending',
crwlimit: 'max',
crwcontinue: crwcontinue,
formatversion: 2
};
if (!crwcontinue && !crwstatuses && titles._) {
params.crwcontinue = `|${titles._}|0`;
}
let response = await new mw.Api().get(params);
let wishes = response?.query?.['communityrequests-wishes'];
if (wishes?.length) {
let $span = $('<span>');
wishes.forEach(w => {
let id = w.crwtitle.match(/^Community Wishlist\/W(\d+)/)?.[1];
if (!id) return;
titles.w[id - 1] = $span.html(w.title).text();
if (crwstatuses === 'declined') {
(titles.wd = titles.wd || []).push(id - 1);
}
let faId = w.crfatitle?.match(/^Community Wishlist\/FA(\d+)/)?.[1];
if (!faId) return;
titles.fa[faId - 1] = w.focusareatitle;
});
if (!crwstatuses) {
titles._ = wishes.at(-1).updated.replace(/\D/g, '');
}
}
let expiry = 86400;
if (crwstatuses || crwcontinue) {
let prev = mw.storage.getObject('_EXPIRY_wishtitles');
if (prev) {
expiry = Math.round(Date.now() / 1000) + 86400 - prev;
}
}
mw.storage.setObject('wishtitles', titles, expiry);
crwcontinue = response?.continue?.crwcontinue;
if (crwcontinue) {
await updateTitles(crwstatuses, crwcontinue);
}
};
let getTitle = id => (
id[0] === 'W' ? titles.w[id.slice(1) - 1] : titles.fa[id.slice(2) - 1]
);
let renderTitle = (title, id, tag = 'span') => {
let classes = 'wishtitle';
if (id[0] === 'W' && titles.wd?.includes(id.slice(1) - 1)) {
classes += ' wishtitle-declined';
}
return $(`<${tag}>`).addClass(classes).append(
$('<a>').attr({
href: `/wiki/Community_Wishlist/${id}`,
title: `Community Wishlist/${id}`
}).text(title)
);
};
let callback = ([id, links]) => {
let title = getTitle(id);
if (!title) {
return true;
}
$(links).after(' ', renderTitle(title, id));
};
let selector = '.mw-changeslist-title, ' +
'.mw-changeslist-log-entry > a:not(.mw-userlink), ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize :is(.mw-changeslist-line-inner, .mw-changeslist-line-inner-comment, .mw-enhanced-rc-nested) > .comment > a, ' +
'#watchlist-edit-form .cdx-table td > label > a, ' +
'.mw-search-result-heading > a:not(:has(> .ext-communityrequests-entity-link--label)), ' +
'.mw-contributions-title, ' +
'#mw-whatlinkshere-list li > bdi > a, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-logevent-loglines > li > a, ' +
'#mw-pages li > a, ' +
'.catchangesviewer-table td:nth-child(3) > a';
mw.hook('wikipage.content').add(async $content => {
let links = {};
$content.find('a').each(function () {
if (!this.matches(selector)) return;
let id = this.textContent.match(
/^(?:Talk:|Translations:)?Community Wishlist\/((?:W|FA)\d+)/
)?.[1];
if (!id) return;
(links[id] = links[id] || []).push(this);
});
links = Object.entries(links);
if (!links.length) return;
await loadTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles('declined');
links.forEach(callback);
});
let pn = mw.config.get('wgRelevantPageName');
let id = pn.match(/^(?:Talk:|Translations:)?Community_Wishlist\/((?:W|FA)\d+)/)?.[1];
if (!id) return;
await $.ready;
let extTitle = document.querySelector('.ext-communityrequests-wish--title');
if (extTitle && $('.mw-pt-languages-selected').attr('lang') === lang) return;
await loadTitles();
let title = getTitle(id);
if (!title) {
await updateTitles();
title = getTitle(id);
if (!title) {
await updateTitles('declined');
title = getTitle(id);
if (!title) return;
}
}
let $title = renderTitle(title, id, 'div');
if (mw.config.get('skin') === 'vector-2022') {
$title.prependTo('.vector-page-toolbar');
} else {
$title.insertAfter('#firstHeading');
}
css.textContent += ' .ext-communityrequests-entity-talk-header{display:none}';
if (extTitle) return;
document.title = document.title.replace(
pn.replaceAll('_', ' '),
`${pn.replace(`Community_Wishlist/${id}`, title)} ($&)`
);
})();
mw.config.get('wgWikiID') === 'metawiki' &&
mw.hook('wikipage.watchlistChange').add(async (isWatched, expiry) => {
if (![0, 1].includes(mw.config.get('wgNamespaceNumber'))) return;
let title = mw.config.get('wgTitle');
if (!/^Community Wishlist\/(?:W|FA)\d+$/.test(title)) return;
if (isWatched) {
await new mw.Api().watch(title + '/Votes', expiry);
mw.notify('Watching /Votes too.');
} else {
await new mw.Api().unwatch(title + '/Votes');
mw.notify('Unwatched /Votes too.');
}
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
$(async () => {
let $input = $('#wpTemplateSandboxTemplate');
if (!$input.length) return;
mw.loader.addStyleTag('#templatesandbox-editform .oo-ui-fieldLayout{max-width:50em} #templatesandbox-editform .oo-ui-fieldLayout-field{flex-grow:999}');
let makeTemplateField = () => new OO.ui.FieldLayout(
new mw.widgets.TitleInputWidget({
inputId: 'wpTemplateSandboxTemplate',
name: 'wpTemplateSandboxTemplate',
showMissing: false,
value: $input.val()
}),
{ label: 'Template name:' }
);
if (mw.loader.getState('ext.TemplateSandbox') !== 'registered') {
await mw.loader.using('mediawiki.widgets');
$input.parent().replaceWith(makeTemplateField().$element);
return;
}
let require = await mw.loader.using([
'ext.TemplateSandbox.TemplateSandboxTitleWidget',
'ext.TemplateSandbox.styles', 'jquery.makeCollapsible', 'user.options'
]);
let widget = new (require('ext.TemplateSandbox.TemplateSandboxTitleWidget'))({
$overlay: true,
id: 'wpTemplateSandboxPage',
maxLength: 255,
name: 'wpTemplateSandboxPage',
placeholder: 'Page title',
required: false,
tabIndex: 10,
templateTitleFunc: () => $('#wpTemplateSandboxTemplate').val()
});
widget.$element.attr('data-ooui', '{"_":"mw.widgets.TemplateSandboxTitleWidget"}')
.data('oouiInfused', widget);
let fieldset = new OO.ui.FieldsetLayout({
classes: ['mw-templatesandbox-fieldset', 'mw-collapsed'],
id: 'templatesandbox-editform',
items: [
makeTemplateField(),
new OO.ui.ActionFieldLayout(
widget,
new OO.ui.ButtonInputWidget({
id: 'wpTemplateSandboxPreview',
name: 'wpTemplateSandboxPreview',
label: 'Show preview',
tabIndex: 10,
type: 'submit',
useInputTag: true
}),
{ align: 'top' }
)
],
label: 'Preview page with this template'
});
fieldset.$label.append(' ', $('<span>').addClass('mw-collapsible-toggle-placeholder'));
fieldset.$group.addClass('mw-collapsible-content');
$('#templatesandbox-editform').replaceWith(fieldset.$element.makeCollapsible());
let modules = ['ext.TemplateSandbox'];
if (Number(mw.user.options.get('uselivepreview'))) {
modules.push('ext.TemplateSandbox.preview');
}
mw.loader.load(modules);
});
mw.config.get('wgWikiID') === 'enwiki' &&
mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist' &&
(async () => {
mw.loader.addStyleTag('.xfdnotifier-sublinks::before{content:" ["} .xfdnotifier-sublinks::after{content:"]"} .xfdnotifier-sublinks > span:not(:first-child)::before{content:"\\2009·\\2009"} .mw-portlet.vector-menu[id^="p-xfdnotifier-"] a{display:inline}');
await mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.storage']);
let xfds = [
{
id: 'rm',
label: 'RM',
full: 'Requested moves',
cat: 'Requested moves',
},
{
id: 'rmt',
label: 'RM/T',
full: 'Requested moves (technical)',
page: 'Wikipedia:Requested_moves/Technical_requests',
titleExtractor: $page => (
$page.find(`[data-mw*='"wt":"RMassist/core"']`).closest('li').map(function () {
return this.querySelector('a[rel="mw:WikiLink"]')?.title;
}).get()
)
},
{
id: 'afd',
label: 'AfD',
full: 'Articles for deletion',
cat: 'Articles for deletion'
},
{
id: 'mfd',
label: 'MfD',
full: 'Miscellaneous for deletion',
cat: 'Miscellaneous pages for deletion'
},
{
id: 'tfd',
label: 'TfD',
full: 'Templates for deletion',
cat: 'Templates for deletion'
},
{
id: 'tfm',
label: 'TfM',
full: 'Templates for merging',
cat: 'Templates for merging'
},
{
id: 'cfd',
label: 'CfD',
full: 'Categories for deletion',
cat: 'Categories for deletion'
},
{
id: 'cfr',
label: 'CfR',
full: 'Categories for renaming',
cat: 'Categories for renaming'
},
{
id: 'cfsr',
label: 'CfSR',
full: 'Categories for speedy renaming',
cat: 'Categories for speedy renaming'
},
{
id: 'cfm',
label: 'CfM',
full: 'Categories for merging',
cat: 'Categories for merging'
},
{
id: 'cfs',
label: 'CfS',
full: 'Categories for splitting',
cat: 'Categories for splitting'
},
{
id: 'cfl',
label: 'CfL',
full: 'Categories for listifying',
cat: 'Categories for listifying'
},
{
id: 'cfc',
label: 'CfC',
full: 'Categories for conversion',
cat: 'Categories for conversion'
},
{
id: 'cfgd',
label: 'CfGD',
full: 'Categories for general discussion',
cat: 'Categories for general discussion'
},
{
id: 'ffd',
label: 'FfD',
full: 'Files for discussion',
cat: 'Wikipedia files for discussion'
},
{
id: 'rfd',
label: 'RfD',
full: 'Redirects for discussion',
cat: 'All redirects for discussion'
},
{
id: 'prod',
label: 'PROD',
full: 'Articles proposed for deletion',
cat: 'All articles proposed for deletion'
}
];
window.xfd = xfds;
let queryTitles = async (xfd, titles) => {
if (!titles.length) return;
let response = await new mw.Api().get({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched) {
xfd.pages.push(p.title);
}
});
await queryTitles(xfd, titles.slice(50));
};
let queryPage = async xfd => {
let $page = $($.parseHTML(await $.get(
`https://en.wikipedia.org/w/rest.php/v1/page/${encodeURIComponent(xfd.page)}/html`
)));
await queryTitles(xfd, xfd.titleExtractor($page));
};
let queryCat = async (xfd, gcmcontinue) => {
let response = await new mw.Api().get({
action: 'query',
prop: 'info|categories',
inprop: 'watched',
clprop: 'sortkey',
clcategories: `Category:${xfd.cat}`,
generator: 'categorymembers',
gcmtitle: `Category:${xfd.cat}`,
gcmlimit: 'max',
gcmsort: 'timestamp',
gcmdir: 'older',
gcmcontinue: gcmcontinue,
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched && p.categories?.[0]?.sortkeyprefix !== ' ') {
xfd.pages.push(p.title);
}
});
if (response?.continue?.gcmcontinue) {
await queryCat(xfd, response.continue.gcmcontinue);
}
};
let show = async (xfd, lastId, isCache) => {
if (xfd.portlet && isCache) return;
let portletId = 'p-xfdnotifier-' + xfd.id;
if (xfd.portlet) {
$(xfd.portlet).find('ul').empty();
if (!xfd.pages.length) return;
} else {
await $.ready;
xfd.portlet = mw.util.addPortlet(portletId, xfd.label, '#' + lastId);
}
let $label = $(`#${portletId}-label`).attr('title', xfd.full);
if (xfd.page) {
$label.wrapInner($('<a>').attr('href', mw.util.getUrl(xfd.page)));
}
xfd.pages.forEach(p => {
let t = mw.Title.newFromText(p);
let isTalk = t.isTalkPage();
let $other = $('<a>').attr({
href: t[isTalk ? 'getSubjectPage' : 'getTalkPage']().getUrl(),
title: isTalk ? 'subject' : 'talk'
}).text(isTalk ? 's' : 't');
let link = mw.util.addPortletLink(portletId, t.getUrl(), p).querySelector('a');
$('<span>').addClass('xfdnotifier-sublinks').append(
$('<span>').append($other),
$('<span>').append(
$('<a>').attr({
href: t.getUrl({ action: 'history' }),
title: 'history'
}).text('h')
)
).insertAfter(link);
});
};
mw.hook('wikipage.content').add(mw.util.throttle(async () => {
let cache = mw.storage.getObject('xfdnotifier') || {};
let lastId = 'p-tb';
for (let xfd of xfds) {
let portletId = 'p-xfdnotifier-' + xfd.id;
let now = Math.floor(Date.now() / 1000);
if (now - cache[xfd.id]?.[0] < 600) {
xfd.pages = cache[xfd.id].slice(1);
await show(xfd, lastId, true);
lastId = portletId;
continue;
}
xfd.pages = [];
if (xfd.cat) {
await queryCat(xfd);
} else if (xfd.page) {
await queryPage(xfd);
}
cache[xfd.id] = [now, ...xfd.pages];
mw.storage.setObject('xfdnotifier', cache, 604800);
await show(xfd, lastId);
lastId = portletId;
}
}, 1800000));
})();
2ryxph1302gmoewsgzfqwawf42jycmf
735816
735815
2026-04-01T11:20:41Z
Nardog
40946
735816
javascript
text/javascript
(async function listTools() {
let pageAction = mw.config.get('wgAction');
let isView = pageAction === 'view';
let isEdit = ['edit', 'submit'].includes(pageAction);
if (!isView && !isEdit) return;
let pageType = mw.config.get('wgCanonicalSpecialPageName') ||
mw.config.get('wgNamespaceNumber');
if (isView && !pageType && !mw.config.exists('wgRedirectedFrom') &&
!mw.config.get('wgIsRedirect') &&
!mw.config.get('wgPageName').includes('/')
) {
return;
}
await mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api',
'mediawiki.interface.helpers.styles'
]);
mw.loader.addStyleTag(`.listtools:not(#mw-content-subtitle .listtools) {
font-size: 85%;
}
.listtools, .listtools a {
font-weight: normal !important;
font-style: normal;
}
.mw-datatable .listtools {
display: block;
}
.listtools + .mw-whatlinkshere-tools,
#watchlist-edit-form .listtools ~ .mw-changeslist-links,
.mw-special-DisambiguationPageLinks .listtools + a {
display: none;
}`);
let messages = Object.assign({
watched: 'Added "$1" to your watchlist',
watchFail: `Couldn't watch "$1"`,
unwatchFail: `Couldn't unwatch "$1"`
}, window.listtoolsMessages);
let getMsg = (key, ...args) => (
Object.hasOwn(messages, key) ? mw.format(messages[key], ...args) : key
);
let notif;
let watchHandler = async function (e) {
e.preventDefault();
let $link = $(this);
let $wrapper = $link.parent();
$link.detach();
let params = new URLSearchParams(this.search);
let action = params.get('action');
$wrapper.text(getMsg(action + 'ing'));
let pn = params.get('title').replaceAll('_', ' ');
let promise = new mw.Api()[action](pn);
if (notif) {
notif.close();
notif = null;
}
try {
let result = await promise;
if (!result || !result[action + 'ed']) throw '';
let newAction = action === 'watch' ? 'unwatch' : 'watch';
params.set('action', newAction);
$link.add(`.listtools-watch > a[href="${this.pathname + this.search}"]`)
.attr('href', this.pathname + '?' + params)
.text(getMsg(newAction));
if (action !== 'watch') return;
let require = await mw.loader.using([
'mediawiki.notification', 'mediawiki.watchstar.widgets'
]);
notif = await mw.notify(
new (require('mediawiki.watchstar.widgets'))('watch', pn, null, $.noop, {
message: getMsg('watched', pn)
}).$element,
{ tag: 'listtools' }
);
} catch {
notif = await mw.notify(getMsg(action + 'Fail', pn), {
tag: 'listtools',
type: 'error'
});
} finally {
$wrapper.html($link);
}
};
let extGetMain = function () {
return this.title;
};
let re = new RegExp(`(?:\\?title=|${
mw.util.escapeRegExp(mw.format(mw.config.get('wgArticlePath'), ''))
})([^#&?]+)`);
let processed = new WeakSet();
let processLinks = ($links, module, titles) => {
let isBatch = !!titles;
titles = titles || new Set();
$links.each(function (i) {
if (processed.has(this)) return;
let $link = $links.eq(i);
let pn;
if (module.useText) {
pn = $link.text();
} else {
let match = $link.attr('href')?.match(re);
if (!match) return;
pn = decodeURIComponent(match[1]);
}
let t = mw.Title.newFromText(pn);
if (!t) return;
if (module.titlesOnly) {
let text = $link.text();
if (text !== pn.replaceAll('_', ' ') &&
(text !== t.getMainText() || t.namespace === 2)
) {
return;
}
}
if ($link.is('.external, .extiw')) {
Object.assign(t, {
getMain: extGetMain,
host: this.host,
namespace: 0,
title: pn
});
} else {
if (t.namespace < 0) return;
if ($link.hasClass('new')) {
t.missing = true;
}
titles.add(t.getSubjectPage().toText());
}
let $tools = $('<span>').addClass('listtools mw-changeslist-links')
.data('listtools', t);
tools.forEach(tool => {
addTool($tools, tool);
});
if ($link.is(':is(del, bdi) > :only-child')) {
if (module.position === 'end') {
$link.parent().parent().append(' ', $tools);
} else {
$link.parent().after(' ', $tools);
}
} else if (module.position === 'end') {
$link.parent().append(' ', $tools);
} else {
$link.after(' ', $tools);
}
if (module.post) {
module.post($tools);
}
processed.add(this);
});
if (!isBatch) {
getWatched(titles);
}
};
let tools = [
{
name: 'edit',
url: t => t.getUrl({ action: 'edit' })
},
{
name: 'hist',
url: t => !t.missing && t.getUrl({ action: 'history' })
},
{
name: 'links',
url: t => mw.util.getUrl('Special:WhatLinksHere/' + t)
},
{
name: 'watch',
url: t => !t.host && t.getSubjectPage().getUrl({ action: 'watch' }),
callback: watchHandler
}
];
let addTool = ($tools, tool, escapedName) => {
let t = $tools.data('listtools');
let $duplicate = escapedName &&
$tools.children('.listtools-' + escapedName);
let url = tool.url;
if (typeof url === 'function') {
url = url(t);
if (!url) {
$duplicate?.remove();
return;
}
}
let $link = $('<a>').attr('href', url).text(getMsg(tool.name));
if (t.host) {
$link.prop('host', t.host);
}
if (tool.callback) {
$link.on('click', tool.callback);
}
let $wrapper = $('<span>').addClass('listtools-' + tool.name)
.append($link);
let $next = tool.next && $tools.children('.listtools-' + tool.next);
if ($next?.length) {
$duplicate?.remove();
$next.before($wrapper);
} else if ($duplicate?.length) {
$duplicate.replaceWith($wrapper);
} else {
$tools.append($wrapper);
}
};
let extend = tool => {
if (tool.label && !Object.hasOwn(messages, tool.label)) {
messages[tool.name] = tool.label;
}
if (tool.next) {
tool.next = $.escapeSelector(tool.next);
}
let existingTool = tools.find(t => t.name === tool.name);
if (existingTool) {
Object.assign(existingTool, tool);
} else {
tools.push(tool);
}
let escapedName = existingTool && $.escapeSelector(tool.name);
let $allTools = $('.listtools');
$allTools.each(function (i) {
addTool($allTools.eq(i), tool, escapedName);
});
};
let getWatched = async titles => {
if (!Array.isArray(titles)) {
titles = [...titles].slice(0, 500);
}
if (!titles.length) return;
(await new mw.Api().post({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages.forEach(page => {
if (!page.watched) return;
$(`.listtools-watch > a[href="${mw.util.getUrl(page.title, { action: 'watch' })}"]`)
.attr('href', mw.util.getUrl(page.title, { action: 'unwatch' }))
.text(getMsg('unwatch'));
});
getWatched(titles.slice(50));
};
mw.hook('listtools.ready').fire(extend);
let catTreeCallback = (records, observer) => {
let $links = $(records[0].target).find('.CategoryTreeItem > bdi > a');
if ($links.length) {
observer.takeRecords();
observer.disconnect();
processLinks($links, catTreeModule);
}
};
let catTreeModule = {
selector: '.CategoryTreeItem > bdi > a',
types: [14, 'CategoryTree'],
position: 'end',
post: $tools => {
$tools.parent().next('.CategoryTreeChildren').each(function () {
new MutationObserver(catTreeCallback)
.observe(this, { childList: true });
});
}
};
let modules = [
{
selector: '#mw-pages li > a, #mw-pages li > span > a',
types: [14]
},
catTreeModule,
{
selector: '#mw-imagepage-section-linkstoimage a, #mw-imagepage-section-globalusage a',
types: [6]
},
{
selector: '#mw-globalusage-result a',
types: ['GlobalUsage']
},
{
selector: '.mw-search-result-heading > a, .searchalttitle > a.mw-redirect, .iw-result__title > a, .mw-search-exists a',
types: ['Search']
},
{
selector: '.mw-search-createlink a',
types: ['Search'],
titlesOnly: true
},
{
selector: '#watchlist-edit-form .cdx-table td > label > a',
types: ['EditWatchlist']
},
{
selector: '.plainlinks > li > a',
types: ['AbuseLog'],
titlesOnly: true
},
{
selector: '#mw-allmessagestable td:first-child > a:first-child:not(.new)',
types: ['Allmessages'],
position: 'end'
},
{
selector: '.mw-spcontent li a',
types: ['DisambiguationPageLinks', 'Listredirects'],
titlesOnly: true
},
{
selector: 'li > a:first-child',
types: ['FileDuplicateSearch']
},
{
selector: '.TablePager_col_title > a:first-child, .TablePager_col_template > a',
types: ['LintErrors'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: 'form > ul > li > a',
types: ['Nuke'],
position: 'end',
titlesOnly: true
},
{
selector: '.page-assessments a',
types: ['PageAssessments'],
titlesOnly: true
},
{
selector: '.TablePager_col_pr_page > a',
types: ['Protectedpages'],
position: 'end'
},
{
selector: '#mw-content-text > ul a',
types: ['Protectedtitles'],
position: 'end'
},
{
selector: '.mw-fr-pending-changes-page-title',
types: ['PendingChanges'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: '#mw-content-text > ul a:first-child',
types: ['StablePages'],
position: 'end'
},
{
selector: '.TablePager_col__page a',
types: ['TopicSubscriptions']
},
{
selector: '.undeleteResult > a',
types: ['Undelete'],
position: 'end',
useText: true
},
{
selector: '.TablePager_col_img_name > a:first-child',
// types: ['Listfiles'],
position: 'end'
},
{
selector: '.mw-newpages-pagename',
post: $tools => {
let $contents = $tools.parent().contents();
$contents.slice(
$contents.index($tools) + 1,
$contents.index($contents.filter('.mw-newpages-length'))
).replaceWith(' ');
}
},
{
selector: '#mw-whatlinkshere-list li > bdi > a'
},
{
selector: '.mw-changeslist-log-entry > a:not(.mw-changeslist-log-gblblock a, .mw-changeslist-log-globalauth a)',
titlesOnly: true
},
{
selector: '.mw-logevent-loglines > li:not(.mw-logline-gblblock, .mw-logline-globalauth) > a',
types: ['Log'],
titlesOnly: true
},
{
selector: '#mw-diff-otitle1 > strong > a, #mw-diff-ntitle1 > strong > a',
types: ['ComparePages'],
position: 'end'
},
{
selector: '#movepage-oldlink, #movepage-newlink',
types: ['Movepage']
},
{
selector: '.mw-undelete-revision a:not(.mw-userlink, .mw-usertoollinks > a)',
types: ['Undelete'],
useText: true
},
{
selector: '.galleryfilename, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner-comment > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-enhanced-rc-nested > .comment > a'
},
{
selector: '.mw-spcontent li a',
position: 'end',
titlesOnly: true
}
];
if (isEdit) {
let post = $tools => {
if (!$tools[0].closest('.templatesUsed')) return;
$tools.parent().contents().last().each(function () {
this.textContent = this.textContent.slice(1);
}).end().slice(-3, -1).remove();
};
let callback = mw.util.debounce(() => {
processLinks(
$('.mw-editfooter-list a, #wikiPreview > .previewnote a'),
{ titlesOnly: true, post }
);
}, 500);
mw.hook('wikipage.editform').add($form => {
callback();
$form.find('.templatesUsed').each(function () {
if (processed.has(this)) return;
processed.add(this);
new MutationObserver(callback)
.observe(this, { childList: true, subtree: true });
});
});
} else if (typeof pageType === 'number') {
$(() => {
processLinks($('.subpages a, .mw-redirectedfrom a, .redirectText a'), {});
});
}
mw.hook('wikipage.content').add($content => {
let titles = new Set();
let $links = $content.find('a');
modules.forEach(module => {
if (module.types && !module.types.includes(pageType)) return;
processLinks($links.filter(module.selector), module, titles);
});
getWatched(titles);
});
}());
mw.hook('listtools.ready').add(extend => {
// extend({
// name: 'talk',
// url: t => !t.isTalkPage() && t.canHaveTalkPage() && t.getTalkPage().getUrl(),
// next: 'hist'
// });
extend({
name: 'subject',
url: t => t.isTalkPage() && t.getSubjectPage().getUrl(),
next: 'hist'
});
extend({
name: 'last',
url: t => !t.missing && t.getUrl({ diff: 'cur', diffonly: 1 }),
next: 'links'
});
// extend({
// name: 'purge',
// url: t => t.getUrl({ action: 'purge' }),
// next: 'watch',
// callback: function (e) {
// e.preventDefault();
// let $link = $(this);
// let $wrapper = $link.parent();
// $link.detach();
// $wrapper.text('purging');
// let pn = $wrapper.closest('.listtools').data('listtools').toText();
// new mw.Api().post({
// action: 'purge',
// forcelinkupdate: 1,
// titles: pn,
// formatversion: 2
// }).then(response => {
// if (response.purge[0].purged) {
// mw.notify(`Purged "${pn}"'`);
// }
// }).always(() => {
// $wrapper.html($link);
// });
// }
// });
extend({
name: 'copy',
url: '#',
callback: function (e) {
e.preventDefault();
let text = $(this).closest('.listtools').data('listtools').toText();
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch (err) {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
}
});
});
(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
mw.config.get('wgCanonicalSpecialPageName') !== 'GlobalContributions' &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector += ', ' + this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i + 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i + 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes += ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i + '/' + count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 + ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 + ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());
if (mw.config.get('wgNamespaceNumber') === 14 && (
mw.config.get('wgAction') === 'view' || !mw.config.get('wgArticleId')
)) {
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox8.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.DateFormatter',
'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget', 'mediawiki.widgets.datetime',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-movement',
'mediawiki.interface.helpers.styles', 'user.options'
]);
}
$(function moveHistory() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Move history', 't-movehistory').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.moveHistoryDialog) {
window.moveHistoryDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox5.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.Title', 'mediawiki.DateFormatter',
'oojs-ui-windows', 'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.DateInputWidget', 'oojs-ui.styles.icons-interactions',
'mediawiki.interface.helpers.styles'
]);
});
});
});
$(function sectionSearch() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Section search', 't-sectionsearch').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.sectionSearchDialog) {
window.sectionSearchDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox7.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-windows',
'mediawiki.widgets', 'mediawiki.widgets.NamespacesMultiselectWidget'
]);
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'CentralAuth' &&
mw.loader.using('jquery.tablesorter', function sortCentralAuthByEditCount() {
mw.hook('wikipage.content').add($content => {
let $table = $content.find('.mw-centralauth-wikislist').has('td');
if (!$table.length) return;
$table.tablesorter().data('tablesorter').sort([{ 4: 'desc' }, { 1: 'asc' }]);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
[10, 828].includes(mw.config.get('wgNamespaceNumber')) &&
!mw.config.get('wgTitle').endsWith('/doc') &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/AutoTestcases.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/TemplatePreviewGuard.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// $(function templatePreviewGuard() {
// let button = document.querySelector('input[name="wpTemplateSandboxPreview"]');
// if (!button) return;
// let proceed;
// button.addEventListener('click', e => {
// if (proceed) {
// proceed = false;
// return;
// }
// e.preventDefault();
// e.stopPropagation();
// let formData = new FormData(button.form);
// let page = formData.get('wpTemplateSandboxPage');
// let temp = formData.get('wpTemplateSandboxTemplate');
// if (!page || !temp) return;
// mw.loader.using('mediawiki.api').then(() => (
// new mw.Api().get({
// action: 'query',
// titles: page,
// prop: 'templates',
// tltemplates: temp,
// formatversion: 2
// })
// )).always(response => {
// if (((((response || {}).query || {}).pages || [])[0] || {}).templates ||
// confirm(`"${page}" doesn't appear to transclude "${temp}". Continue?`)
// ) {
// proceed = true;
// button.click();
// }
// });
// }, true);
// if (!mw.config.get('wgArticleId')) return;
// let widgetEl = document.querySelector('#wpTemplateSandboxPage.oo-ui-widget');
// if (!widgetEl) return;
// let pn = mw.config.get('wgPageName').replace(/_/g, ' ');
// mw.loader.using(['mediawiki.api', 'oojs-ui-core']).then(() => (
// new mw.Api().get({
// action: 'query',
// titles: pn,
// prop: 'transcludedin',
// tiprop: 'title',
// tilimit: 'max',
// formatversion: 2
// })
// )).then(response => {
// if (!response.batchcomplete) return;
// let pages = response.query.pages[0].transcludedin
// .filter(o => o.title !== pn);
// if (!pages.length) return;
// let widget = OO.ui.infuse(widgetEl);
// if (pages.length === 1) {
// widget.setValue(pages[0].title);
// return;
// }
// widget.$element.replaceWith(
// new OO.ui.ComboBoxInputWidget({
// id: 'wpTemplateSandboxPage',
// maxlength: widget.$input.prop('maxLength'),
// name: widget.$input.prop('name'),
// options: pages
// .sort((a, b) => a.ns - b.ns || -(a.title < b.title))
// .map(o => ({ data: o.title })),
// placeholder: widget.$input.prop('placeholder'),
// tabIndex: widget.getTabIndex(),
// value: widget.getValue()
// }).on('enter', e => {
// e.preventDefault();
// button.click();
// }).$element
// );
// });
// });
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(async () => {
let form = document.getElementById('editform');
if (!form) return;
let formData = new FormData(form);
let section = formData.get('wpSection');
if (section === 'new') return;
let widget = document.getElementById('wpSummaryWidget');
if (!widget) return;
let isOld = formData.get('altBaseRevId') > 0 ||
(formData.get('baseRevId') || formData.get('parentRevId')) !== formData.get('editRevId');
await mw.loader.using([
'jquery.textSelection', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core',
'oojs-ui.styles.icons-editing-core'
]);
let $textarea = $('#wpTextbox1');
let input = OO.ui.infuse(widget);
let button = new OO.ui.ButtonWidget({
framed: false,
icon: 'undo',
classes: ['autosectionlink-button'],
invisibleLabel: true,
label: 'Restore previous section link'
}).toggle().on('click', () => {
let cache = button.getData();
input.setValue(input.getValue().replace(
/^(\/\*.*?\*\/)?\s*/,
cache[0] ? '/* ' + cache[0] + ' */ ' : ''
));
updatePreview(cache[0]);
cache.reverse();
}).on('toggle', () => {
input.$input.css('width', `calc(100% - ${button.$element.width()}px)`);
});
input.$input.after(button.$element);
let update = mw.util.debounce($diff => {
let lines = $textarea.textSelection('getContents').replace(/\s+$/, '').split('\n');
let firstLineNum;
if (isOld) {
let i, lastLineNum;
$diff.find('td:last-child').each(function () {
if (this.classList.contains('diff-lineno')) {
i = this.textContent.replace(/\D+/g, '') - 1;
} else if (this.classList.contains('diff-context')) {
i++;
} else if (this.classList.contains('diff-addedline')) {
i++;
if (!firstLineNum) {
firstLineNum = i;
}
lastLineNum = i;
} else if (this.classList.contains('diff-empty')) {
if (!firstLineNum) {
firstLineNum = i === 0 ? 1 : i;
}
lastLineNum = i;
}
});
lines.length = lastLineNum || 0;
} else {
let origLines = $textarea.prop('defaultValue').replace(/\s+$/, '').split('\n');
firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
if (!firstLineNum) {
firstLineNum = lines.length < origLines.length
? lines.length
: 1;
}
for (let i = 1, x = lines.length, y = origLines.length;
(section ? i < x : i <= x) && lines[x - i] === origLines[y - i];
i++
) {
lines.pop();
}
}
let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 7;
lines.slice(firstLineNum).forEach(line => {
let match = line.match(re);
if (match && match[1].length < lowest) {
lowest = match[1].length;
}
});
let head;
lines.slice(0, firstLineNum).reverse().some(line => {
let match = line.match(re);
if (match && match[1].length < lowest) {
head = match[2];
return true;
}
});
if (head) {
head = head
.replace(/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
.replace(/''(.+?)''/g, '$1')
.trim();
} else if (typeof firstLineNum === 'number' && section < 1 && lowest === 7) {
head = '';
}
let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
let prev = match[1];
if (prev === head) return;
input.setValue((typeof head === 'string' ? '/* ' + head + ' */ ' : '') + match[2]);
button.setData([prev, head]).toggle(true);
updatePreview(head);
}, 500);
let updatePreview = head => {
let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
if (!$preview.length) return;
let hasHead = typeof head === 'string';
let url = hasHead && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
let text = hasHead && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + (head || mw.messages.get('autocomment-top', '(top)'));
let $ac = $preview.children('.autocomment:first-child');
if ($ac.length && !$ac[0].previousSibling) {
if (hasHead) {
$ac.children('a').attr('href', url).text(text);
} else {
let node = $ac[0].nextSibling;
if (node?.nodeType === 3) {
node.textContent = node.textContent.replace(/^\s+/, '');
}
$ac.remove();
}
} else if (hasHead) {
$('<span>').addClass('autocomment').append(
$('<a>').attr({
href: url,
title: mw.config.get('wgPageName').replace(/_/g, ' ')
}).text(text),
mw.messages.get('colon-separator', ': ')
).prependTo($preview);
}
};
if (isOld) {
mw.hook('wikipage.diff').add(update);
} else {
$textarea.on('input', update);
mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
if (on && $codeMirror[0].CodeMirror) {
$codeMirror[0].CodeMirror.on('change', update);
}
});
mw.hook('ext.CodeMirror.input').add(update);
update();
}
new mw.Api().loadMessagesIfMissing(['autocomment-top', 'colon-separator']);
mw.loader.addStyleTag('.autosectionlink-button{position:absolute;top:0;right:0;margin:0}');
});
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(function copyRevId() {
let handler = function (e) {
e.preventDefault();
let text = this.closest('.diff td')?.querySelector('[data-mw-revid]')?.dataset.mwRevid ||
this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!text) return;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
document.execCommand('copy');
$input.remove();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id')
)
);
});
}());
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(() => {
let handler = async function (e) {
e.preventDefault();
let td = this.closest('.diff td');
let rev = td
? td.querySelector('[data-mw-revid]')?.dataset.mwRevid
: this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!rev) {
mw.notify(`Couldn't get the revision.`, {
tag: 'markasunseen',
type: 'error'
});
return;
}
let pn = td
? new URLSearchParams([...td.querySelectorAll('a')].pop()?.search).get('title')
: mw.config.get('wgPageName');
if (!pn) return;
await mw.loader.using('mediawiki.api');
let result = (await new mw.Api().postWithEditToken({
action: 'setnotificationtimestamp',
[td ? 'newerthanrevid' : 'torevid']: rev,
titles: pn,
formatversion: 2
})).setnotificationtimestamp?.[0];
if (Object.hasOwn(result, 'notificationtimestamp')) {
mw.notify(`Marked revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'success'
});
} else if (result?.notwatched) {
mw.notify('This page is not on your watchlist.', {
tag: 'markasunseen',
type: 'warn'
});
} else {
mw.notify(`Couldn't mark revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'error'
});
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions after this one as unseen'
}).on('click', handler).text('unseen'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions since this one as unseen'
}).on('click', handler).text('unseen')
)
);
});
})();
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
((mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4) ||
(mw.config.get('wgWikiID') === 'metawiki' && mw.config.get('wgPageContentModel') === 'wikitext')) &&
mw.loader.using(['mediawiki.util', 'mediawiki.Title'], function copyUnsig() {
let handler = function (e) {
e.preventDefault();
let parent = this.closest('li, td');
let ts = parent.textContent.match(/\d\d:\d\d, \d\d? [A-Z][a-z]+ \d{4}/)?.[0];
if (!ts) return;
let user = parent.querySelector('.mw-userlink').textContent;
if (mw.util.isIPv6Address(user)) {
user = user.toUpperCase();
}
let temp = mw.util.isIPAddress(user) ? 'unsigned IP' : 'unsigned';
let text = `{{subst:${temp}|${user}|${ts}}}`;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').filter(function () {
if (mw.config.get('wgWikiID') === 'metawiki') {
return true;
}
let link = this.querySelector('strong > a') ||
this.parentElement.querySelector('#differences-prevlink, #differences-nextlink');
if (!link) return;
let t = mw.Title.newFromText(mw.util.getParamValue('title', link.search));
return t.isTalkPage() || t.namespace === 4;
}).append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig')
)
);
});
});
// mw.config.get('wgAction') === 'history' &&
// mw.loader.using('mediawiki.util', function () {
// mw.hook('wikipage.content').add($content => {
// $content.find('a.mw-changeslist-date').after(function () {
// return [
// ' (',
// $('<a>').attr('href', mw.util.getUrl(null, {
// action: 'edit',
// oldid: this.closest('li').dataset.mwRevid
// })).text('e'),
// ')'
// ];
// });
// });
// });
// ['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
// mw.hook('wikipage.content').add($content => {
// $content.find('.mw-changeslist-history').parent().after(function () {
// return $('<span>').append(
// $('<a>').attr(
// 'href',
// this.firstElementChild.getAttribute('href').slice(0, -7) + 'edit'
// ).text('e')
// );
// });
// });
if (screen.width < 500) {
mw.loader.addStyleTag('@font-face{font-family:CharisW;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/017b2b2ad86e09d3c22b8cf0dfc78247/CharisSILRegular.ttf) format(truetype)} @font-face{font-family:CharisW;font-weight:700;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/6f5069ac6a300dad45383c952e92c573/CharisSILBold.ttf) format(truetype)} body .IPA{font-family:CharisW,sans-serif} .mw-highlight-lines > pre{width:120em}');
location.hash && $(() => {
let target = document.querySelector(':target');
if (target?.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
});
}
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
(mw.config.exists('wgCodeEditorCurrentLanguage') ||
mw.config.exists('cmMode') && mw.config.get('cmMode') !== 'mediawiki') &&
(function saveNEdit() {
let notif;
$(document.body).on('click', '#wpSave', async function (e) {
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey ||
e.originalEvent?.defaultPrevented
) {
return;
}
e.preventDefault();
await mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'jquery.textSelection', 'oojs-ui-core'
]);
let button = OO.ui.infuse(this.parentElement).setDisabled(true);
let $textarea = $('#wpTextbox1');
let text = $textarea.textSelection('getContents');
let $summary = $('#wpSummary');
let formData = new FormData(this.form);
let promise = new mw.Api().postWithEditToken({
action: 'edit',
title: mw.config.get('wgPageName'),
text: text,
section: formData.get('wpSection') || undefined,
summary: $summary.textSelection('getContents'),
[$('#wpMinoredit').prop('checked') ? 'minor' : 'notminor']: 1,
baserevid: formData.get('editRevId'),
basetimestamp: formData.get('wpEdittime'),
starttimestamp: formData.get('wpStarttime'),
watchlist: $('#wpWatchthis').prop('checked') ? 'watch' : 'unwatch',
watchlistexpiry: formData.get('wpWatchlistExpiry') || undefined,
undo: formData.get('wpUndidRevision') || undefined,
undoafter: formData.get('wpUndoAfter') || undefined,
contentformat: formData.get('format'),
contentmodel: formData.get('model'),
assertuser: mw.config.get('wgUserName'),
formatversion: 2
});
notif?.close();
notif = null;
try {
let response = await promise;
if (response?.edit?.result !== 'Success') throw '';
$('#editform > input[name="wpUndidRevision"], #editform > input[name="wpUndoAfter"]').remove();
$textarea.data('origtext', text).prop('defaultValue', text);
$summary.val($summary.prop('defaultValue'));
if (mw.loader.getState('mediawiki.editRecovery.edit') === 'ready') {
let storage = mw.loader.moduleRegistry['mediawiki.editRecovery.edit'].packageExports['storage.js'];
storage.deleteData(mw.config.get('wgPageName'));
storage.closeDatabase();
}
notif = await mw.notify(response.edit.nochange ? 'No change' : [
document.createTextNode('Saved'),
$('<p>').append(
new OO.ui.ButtonWidget({
href: mw.util.getUrl(),
target: '_blank',
label: 'View'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, {
diff: response.edit.newrevid || 'cur',
diffonly: 1
}),
target: '_blank',
label: 'Diff'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, { action: 'history' }),
target: '_blank',
label: 'History'
}).$element
)[0]
], { tag: 'savenedit' });
} catch (error) {
notif = await mw.notify(error?.error?.info || error || 'Save failed', {
autoHideSeconds: 'long',
tag: 'savenedit',
type: 'error'
});
} finally {
button.setDisabled();
}
});
}());
mw.config.get('wgNamespaceNumber') === 0 &&
mw.config.get('wgAction') === 'view' &&
mw.config.get('wgCategories')?.some(c => c.endsWith(' actors') || c.endsWith(' actresses')) &&
$(() => {
let n = $.escapeSelector(mw.config.get('wgTitle').replace(/ \(.+\)$/, ''));
let $links = $(`.hatnote a[title$="${n} filmography"], .hatnote a[title*="${n} on "], .hatnote a[title*="${n} performances"]`);
if (!$links.length) return;
let titles = {};
$links = $links.filter(function () {
let text = this.textContent;
return !(titles[text] = Object.hasOwn(titles, text));
});
mw.notify(
$links.length === 1
? $links.clone()
: $('<ul>').append($links.clone().wrap('<li>').parent()),
{ autoHideSeconds: 'long' }
);
});
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
let os = mw.user.options.get('userjs-rcmuter');
let set = new Set(os && os.split('|'));
let save = () => {
let ns = [...set].join('|');
if (ns === mw.user.options.get('userjs-rcmuter')) return;
new mw.Api().saveOption('userjs-rcmuter', ns);
mw.user.options.set('userjs-rcmuter', ns);
$edit.attr('data-rcmuter', set.size);
};
mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
let $edit = $('<a>').attr({
class: 'rcmuter-edit',
href: '#',
'data-rcmuter': set.size
}).text('Edit muted').on('click', e => {
e.preventDefault();
mw.loader.using([
'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
let multiselect = new mw.widgets.UsersMultiselectWidget({
$overlay: dialog.$overlay,
ipAllowed: true,
selected: [...set]
}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
let instance = dialog.open({
message: $([
document.createTextNode('Muted users:'),
multiselect.$element[0]
]),
size: 'medium'
});
instance.opened.then(() => {
setTimeout(() => {
multiselect.focus().menu.toggle(false);
});
});
instance.closed.then(result => {
if (!result || result.action !== 'accept') return;
set = new Set(multiselect.getSelectedUsernames());
save();
mw.notify('Changes will take effect in next load.', {
tag: 'rcmuter'
});
});
});
});
let buttonsShown;
let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
e.preventDefault();
if (buttonsShown) {
mw.hook('wikipage.content').remove(addButtons);
$('.rcmuter-toggle').remove();
this.textContent = 'Show toggle buttons';
} else {
mw.hook('wikipage.content').add(addButtons);
this.textContent = 'Hide toggle buttons';
}
buttonsShown = !buttonsShown;
});
let $toggle = $('<a>').attr({
class: 'rcmuter-togglemuted',
href: '#'
}).text('Show muted').on('click', function (e) {
e.preventDefault();
this.textContent = document.body.classList.toggle('rcmuter-disabled')
? 'Hide muted'
: 'Show muted';
});
let $toggleSpan = $('<span>').hide().append($toggle);
mw.util.addSubtitle(
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append($edit),
$('<span>').append($toggleButtons),
$toggleSpan
)[0]
);
let toggle = function (e) {
e.preventDefault();
let user = $(this)
.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
.last().text().trim();
if (!user) {
mw.notify(`Can't retrieve the username.`, {
tag: 'rcmuter',
type: 'error'
});
return;
}
let muting = this.parentElement.classList.toggle('rcmuter-unmute');
set[muting ? 'add' : 'delete'](user);
save();
this.textContent = muting ? 'unmute' : 'mute';
mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
tag: 'rcmuter'
});
};
let addButtons = $content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) {
$content = $('#mw-content-text');
if ($content.has('.rcmuter-toggle').length) return;
}
let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
let $muted = $tools.filter('.rcmuter-muted *');
$tools.not($muted).append(
$('<span>').addClass('rcmuter-toggle').append(
$('<a>').attr('href', '#').text('mute').on('click', toggle)
)
);
if (!$muted.length) return;
$muted.append(
$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
$('<a>').attr('href', '#').text('unmute').on('click', toggle)
)
);
};
let mutedCount;
let filter = function () {
let muted = set.has(this.textContent);
if (muted) mutedCount++;
return muted;
};
mw.hook('wikipage.content').add($content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) return;
if (!set.size) {
$toggleSpan.hide();
return;
}
mutedCount = 0;
$content.find('.changedby > .mw-userlink:only-child')
.filter(filter).closest('table').addClass('rcmuter-muted');
$content.find('.mw-userlink:not(.changedby > *, .comment *, .rcmuter-muted *)')
.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
$toggleSpan.toggle(!!mutedCount);
$toggle.attr('data-rcmuter', mutedCount);
});
});
location.hostname.endsWith('.wikipedia.org') &&
mw.config.get('wgNamespaceNumber') % 2 === 0 &&
// mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.util')).then(function refRenamer() {
if (!document.getElementById('p-tb')) return;
let messages = Object.assign({
portlet: 'RefRenamer',
loading: 'Loading RefRenamer...'
}, window.refrenamerMessages);
let clicked;
mw.util.addPortletLink('p-tb', '#', messages.portlet, 't-refrenamer').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.refRenamer) {
window.refRenamer();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox6.js&action=raw&ctype=text/javascript');
mw.notify(messages.loading, {
autoHideSeconds: 'long',
tag: 'refrenamer'
});
});
});
if (['edit', 'submit'].includes(mw.config.get('wgAction'))) {
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/ExpandContractions.js&action=raw&ctype=text/javascript', 's');
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/Unpipe.js&action=raw&ctype=text/javascript', 's');
}
mw.config.get('wgAction') !== 'history' &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/CopyCodeBlock.js&action=raw&ctype=text/javascript', 's');
mw.config.exists('wgDiffNewId') &&
mw.config.get('wgDiscussionToolsFeaturesEnabled') &&
(function () {
let data = {}, clickHandler, autoClear, run;
window.dtc = data;
let highlight = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
mw.loader.moduleRegistry['ext.discussionTools.init'].packageExports['highlighter.js']
.highlightNewComments(mw.dt.pageThreads, true, ids);
if (clickHandler) {
$(document.body).off('click', clickHandler);
return;
}
$._data(document.body, 'events').click.some(o => {
if (String(o.handler).includes('highlighter.clearHighlightTargetComment(')) {
$(document.body).off('click', o.handler);
clickHandler = o.handler;
return true;
}
});
$._data(window, 'events').popstate.some(o => {
if (String(o.handler).includes('highlighter.highlightTargetComment(')) {
$(window).off('popstate', o.handler);
return true;
}
});
};
let scroll = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
let yToSpan = Object.fromEntries(
ids.map(id => document.getElementById(id)).filter(Boolean)
.map(span => [span.getBoundingClientRect().y, span])
);
let ys = Object.keys(yToSpan);
if (!ys.length) return;
let lower = ys.filter(y => y > 10);
if (!lower.length ||
Math.max(...lower) < document.documentElement.clientHeight
) {
yToSpan[Math.min(...ys)].scrollIntoView();
} else {
yToSpan[Math.min(...lower)].scrollIntoView();
}
};
let scrollToNext = function (e) {
e.preventDefault();
let revId = mw.config.get('wgDiffOldId');
if (!revId || !data[revId]) return;
let i = data[revId].indexOf(
this.closest('[data-mw-thread-id]').dataset.mwThreadId
);
if (i === -1) return;
let next = data[revId][i + 1] || data[revId][0];
document.getElementById(next).scrollIntoView();
};
mw.hook('wikipage.content').add(async $content => {
let revId = mw.config.get('wgDiffOldId');
if (!revId) return;
let param = new URLSearchParams(location.search).get('diffonly');
if (param && param !== '0') return;
if (data[revId]) {
highlight(revId);
return;
}
await mw.loader.using(['ext.discussionTools.init', 'mediawiki.util']);
let begin = Date.parse($('#mw-diff-otitle1 .mw-diff-timestamp').data('timestamp'));
data[revId] = mw.dt.pageThreads.getCommentItems()
.filter(c => c.timestamp > begin).map(c => c.id);
if (!data[revId].length) return;
await new Promise(setTimeout);
highlight(revId);
$content.find('.ext-discussiontools-init-replylink-buttons').filter(function () {
return data[revId].includes(this.dataset.mwThreadId);
}).children('span:last-of-type').before(
' | ',
$('<a>').attr({
href: '#',
role: 'button'
}).text('next').on('click', scrollToNext)
);
if (run || !document.getElementById('p-tb')) return;
run = true;
let portlet = mw.util.addPortletLink('p-tb', '#', 'Scroll to next', 't-scrolltonext');
portlet.firstElementChild.addEventListener('click', e => {
e.preventDefault();
scroll(mw.config.get('wgDiffOldId'));
});
mw.util.addPortletLink('p-tb', '#', 'Toggle highlight', 't-togglehighlight').firstElementChild.addEventListener('click', e => {
e.preventDefault();
autoClear = !autoClear;
if (autoClear) {
$(document.body).on('click', clickHandler)[0].click();
} else {
highlight(mw.config.get('wgDiffOldId'));
}
});
mw.loader.addStyleTag(`#t-scrolltonext{position:fixed;bottom:${portlet.clientHeight}px} #t-togglehighlight{position:fixed;bottom:0}`);
});
}());
mw.config.get('wgNamespaceNumber') === 6 &&
mw.config.get('wgAction') === 'view' &&
mw.hook('wikipage.content').add($content => {
$content.find('.filehistory .mw-usertoollinks-contribs').after(function () {
return [
' | ',
$('<a>').attr('href', `${
mw.config.get('wgScript')
}?title=Special:ListFiles/${
this.pathname.replace(/^.+\//, '')
}&ilshowall=1`).text('uploads')
];
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function () {
if (!$('input[name="wpSection"]').val()) return;
mw.hook('wikipage.content').add(async $content => {
let $refs = $content.find('.mw-ext-cite-warning-sectionpreview_no_text');
if (!$refs.length) return;
let ids = {};
$refs.each(function () {
ids[this.closest('[id]').id.replace(/-\d+$/, '')] = this;
});
let response = await $.get(`/api/rest_v1/page/html/${encodeURIComponent(mw.config.get('wgPageName'))}`);
$($.parseHTML(response)).find('.mw-reference-text').each(function () {
ids[this.id.replace(/^mw-reference-text-|-\d+$/g, '')]?.replaceWith(this);
});
});
});
mw.hook('moremenu.ready').add(config => {
$('#mm-page-purge-cache > a').on('click', e => {
e.preventDefault();
new mw.Api().post({
action: 'purge',
forcelinkupdate: 1,
titles: config.page.name,
formatversion: 2
}).then(() => {
location.href = mw.util.getUrl();
});
});
$('#mm-page-search-search-history-wikiblame > a').on('click', function (e) {
e.preventDefault();
let q = prompt();
if (q === null) return;
let href = this.href;
if (q) {
let removal = q[0] === '!';
if (removal) {
q = q.slice(1);
}
href += '&needle=' + encodeURIComponent(q);
if (removal) {
href += '&binary_search_inverse=on';
}
href += '&force_wikitags=on';
}
open(href, '_blank');
});
$('#mm-page-expand-templates > a').on('click auxclick', function (e) {
if (e.which > 2) return;
e.preventDefault();
let revId = mw.config.get('wgRevisionId') || Number($('input[name=oldid]').val());
let url = revId
? '/w/rest.php/v1/revision/' + revId
: '/w/rest.php/v1/page/' + config.page.encodedName;
$.get(url).then(response => {
$('<form>').attr({
method: 'post',
action: this.href,
target: '_blank'
}).append(
[
['wpInput', response.source],
['wpContextTitle', config.page.name],
['wpRemoveComments', 1]
].map(([n, v]) => $('<input>').attr({
name: n,
type: 'hidden'
}).val(v))
).appendTo(document.body).trigger('submit').remove();
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'ApiSandbox' &&
mw.hook('apisandbox.formatRequest').add((...args) => {
args[4].complete = function () {
setTimeout(() => {
mw.hook('wikipage.content').fire($('.oo-ui-pageLayout-active'));
}, 100);
};
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.storage')).then(async () => {
let infuseAndCall = (query, method, ...args) => {
let $widget = $(query);
if ($widget.length) {
return OO.ui.infuse($widget)[method](...args);
}
};
let section = $('input[name="wpSection"]').val();
if (section) {
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let save = () => {
let newSource = $textarea.textSelection('getContents');
if (newSource === source) {
mw.storage.session.remove('editfullpage');
} else {
mw.storage.session.setObject('editfullpage', [
mw.config.get('wgPageName'),
section,
newSource.trimEnd(),
infuseAndCall('#wpSummaryWidget', 'getValue') || '',
Number(infuseAndCall('#wpMinoreditWidget', 'isSelected')) || 0,
Number(infuseAndCall('#wpWatchthisWidget', 'isSelected')) || 0,
infuseAndCall('#wpWatchlistExpiryWidget', 'getValue') || 'infinite'
]);
}
};
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
setInterval(() => {
mw.requestIdleCallback(save);
}, 3000);
window.addEventListener('beforeunload', save);
return;
}
let data = mw.storage.session.getObject('editfullpage');
mw.storage.session.remove('editfullpage');
console.log(data);
if (!data || data[0] !== mw.config.get('wgPageName')) return;
let isNew = data[1] === 'new';
let isLead = data[1] === '0';
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let newSource, start, msg, notifOpts = { autoHideSeconds: 'long' };
let orig = [];
if (isNew) {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
newSource = source + (data[3] ? '\n== ' + data[3] + ' ==\n\n' : '\n') + data[2] + '\n';
start = source.length;
} else {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core', 'mediawiki.api']);
let { parse } = await new mw.Api().get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
wrapoutputclass: '',
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
formatversion: 2
});
let target = !isLead && parse.sections.find(s => s.index === data[1]);
if (isLead || target) {
let next = parse.sections.find(s => s.index - 1 === Number(data[1]));
newSource = (isLead ? '' : [...source].slice(0, target.byteoffset)).join('') +
data[2] + (next ? '\n\n' + [...source].slice(next.byteoffset).join('') : '\n');
start = isLead ? 0 : target.byteoffset;
} else {
newSource = source + '\n\n' + data[2] + '\n';
start = source.length;
msg = `Section restored. Couldn't find the section. The source is appended at bottom.`;
notifOpts.type = 'warn';
}
orig[0] = infuseAndCall('#wpSummaryWidget', 'getValue');
infuseAndCall('#wpSummaryWidget', 'setValue', data[3]);
}
$textarea.textSelection('setContents', newSource);
orig[1] = infuseAndCall('#wpMinoreditWidget', 'getSelected');
infuseAndCall('#wpMinoreditWidget', 'setSelected', data[4]);
orig[2] = infuseAndCall('#wpWatchthisWidget', 'getSelected');
infuseAndCall('#wpWatchthisWidget', 'setSelected', data[5]);
orig[3] = infuseAndCall('#wpWatchlistExpiryWidget', 'getValue');
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', data[6]);
setTimeout(() => {
$textarea.textSelection('setSelection', { start });
});
let notif = await mw.notify($([
document.createTextNode(msg || 'Section restored.'),
$('<p>').append(
new OO.ui.ButtonWidget({
flags: 'destructive',
label: 'Discard'
}).on('click', () => {
$textarea.textSelection('setContents', source);
if (orig[0]) {
infuseAndCall('#wpSummaryWidget', 'setValue', orig[0]);
}
infuseAndCall('#wpMinoreditWidget', 'setSelected', orig[1]);
infuseAndCall('#wpWatchthisWidget', 'setSelected', orig[2]);
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', orig[3]);
notif.close();
}).$element
)[0]
]), notifOpts);
});
mw.config.exists('wgPostEdit') &&
mw.loader.using('mediawiki.storage', () => {
mw.storage.session.remove('editfullpage');
});
mw.config.get('wgAction') === 'history' &&
mw.hook('wikipage.content').add(async $content => {
if (!$content.has('.mw-history-line-updated').length) return;
let href = $content.find('a.mw-history-histlinks-current:not(.mw-history-line-updated a)').attr('href');
if (!href) {
await mw.loader.using(['mediawiki.api', 'mediawiki.util']);
let page = (await new mw.Api().get({
action: 'query',
titles: mw.config.get('wgPageName'),
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev >= page.lastrevid) return;
href = mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
}
$content.find('.mw-history-compareselectedversions-button').first().after(
' ',
$('<a>').attr({
class: 'unseendiff',
href: href
}).text('unseen')
);
});
(async () => {
let cspn = mw.config.get('wgCanonicalSpecialPageName');
let isBp = cspn === 'Blankpage';
if (!isBp && cspn !== 'Watchlist') return;
await mw.loader.using('mediawiki.util');
let notify = async (text, options, pn) => {
let msg = [document.createTextNode(text)];
if (pn) {
msg.push(
$('<p>').append(
$('<a>').attr('href', mw.util.getUrl(pn)).text(pn),
' ',
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'edit' }))
.text('edit')
),
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'history' }))
.text('history')
)
)
)[0]
);
}
if (isBp) {
await $.ready;
$('#mw-content-text').html(msg);
} else {
return mw.notify(msg, Object.assign(options || {}, {
tag: 'unseendiff'
}));
}
};
let getUrl = async pn => {
await mw.loader.using('mediawiki.api');
let page = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
if (!page.notificationtimestamp) {
notify(`Couldn't get the last seen time.`, {
type: 'warn'
}, pn);
return;
}
let rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (rev === page.lastrevid) {
notify('Already seen.', {
type: 'warn'
}, pn);
return;
}
if (!rev) {
rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
rvdir: 'newer',
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev) {
notify(`Couldn't get the last seen revision.`, {
type: 'warn'
}, pn);
return;
}
}
if (rev > page.lastrevid) {
notify(`Invalid rev for "${pn}" (rev: ${rev}, lastrevid: ${page.lastrevid})`, {
autoHideSeconds: 'long',
type: 'warn'
}, pn);
return;
}
return mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
};
if (isBp) {
let pn = mw.config.get('wgTitle').match(/^[^/]+\/unseendiff\/(.+)$/)?.[1];
if (!pn) return;
notify('Loading...', null, pn);
let href = await getUrl(pn);
if (!href) return;
notify('Redirecting...', null, pn);
location.href = href;
return;
}
let handler = async function (e) {
if (e.which > 2) return;
e.preventDefault();
let pn = this.dataset.pn;
if (!pn) {
notify(`Couldn't get the page name.`, {
type: 'error'
});
return;
}
let notifPromise = notify('Loading...', {
autoHideSeconds: 'long'
});
let href = await getUrl(pn);
if (!href) return;
$(`.unseendiff-loader[data-pn="${$.escapeSelector(pn)}"]`).attr({
class: 'unseendiff',
href: href,
target: '_blank'
}).off('click auxclick', handler);
if (e.type === 'auxclick' || e.ctrlKey || e.metaKey || e.shiftKey) {
open(href);
} else {
this.click();
}
(await notifPromise).close();
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-changeslist-src-mw-edit.mw-changeslist-watchedunseen:not(.mw-changeslist-watchedseen) .mw-changeslist-line-inner'
).each(function () {
let pn = this.dataset.targetPage ||
this.closest('[data-target-page]')?.dataset.targetPage ||
this.closest('table.mw-enhanced-rc')?.querySelector('[data-target-page]')?.dataset.targetPage;
if (!pn) return;
$('<span>').append(
$('<a>').attr({
class: 'unseendiff-loader',
href: mw.util.getUrl(`Special:BlankPage/unseendiff/${pn}`),
'data-pn': pn
}).on('click auxclick', handler).text('unseen')
).appendTo(
[...this.querySelectorAll('.mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
});
})();
['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
mw.loader.using('mediawiki.util', () => {
let watched = new Set();
let query = async lis => {
let titles = Object.keys(lis).slice(0, 50);
if (!titles.length) return;
await mw.loader.using('mediawiki.api');
let pages = (await new mw.Api().post({
action: 'query',
titles: titles,
prop: 'info',
inprop: 'notificationtimestamp|watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages;
for (let page of pages) {
if (!Object.hasOwn(lis, page.title)) continue;
if (page.watched) {
watched.add(page);
$(lis[page.title]).addClass('watched');
}
if (!page.notificationtimestamp) continue;
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev === page.lastrevid) continue;
if (rev > page.lastrevid) {
mw.notify($([
document.createTextNode('Invalid rev for "'),
$('<a>').attr({
href: mw.util.getUrl(page.title, { action: 'history' }),
target: '_blank'
}).text(page.title)[0],
document.createTextNode(`" (rev: ${rev}, lastrevid: ${page.lastrevid})`),
]), {
autoHideSeconds: 'long',
type: 'warn'
});
continue;
}
$('<span>').append(
$('<a>').attr({
class: 'unseendiff',
href: mw.util.getUrl(page.title, {
diff: page.lastrevid,
oldid: rev
})
}).text('unseen')
).appendTo(
lis[page.title].map(li => (
[...li.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(li).before(' ')
))
);
}
titles.forEach(title => {
delete lis[title];
});
query(lis);
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-contributions-list > li:not(.mw-contributions-current)[data-mw-revid]'
).each(function () {
let link = this.querySelector('a.mw-changeslist-date, a.mw-changeslist-history');
let pn = link ? new URLSearchParams(link.search).get('title') : '';
$('<span>').append(
$('<a>').attr({
class: 'mw-changeslist-diff',
href: mw.util.getUrl(pn, {
diff: 'cur',
oldid: this.dataset.mwRevid
})
}).text('cur')
).appendTo(
[...this.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
if (mw.config.get('wgWikiID') === 'wikidatawiki') return;
let lis = {};
$content.find('.mw-contributions-title').each(function () {
let title = this.textContent;
if (!Object.hasOwn(lis, title)) {
lis[title] = [];
}
lis[title].push(this.closest('li'));
});
Object.keys(lis).forEach(title => {
if (watched.has(title)) {
$(lis[title]).addClass('watched');
delete lis[title];
}
});
query(lis);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox9.js&action=raw&ctype=text/javascript');
mw.config.get('wgWikiID') === 'metawiki' &&
(async () => {
let css = mw.loader.addStyleTag(`.wishtitle {
font-size: 90%;
font-style: italic;
word-break: break-word;
}
.wishtitle > a {
color: var(--color-warning, #886425);
}
.wishtitle > a:visited {
color: var(--border-color-warning--hover, #735421);
}
.wishtitle-declined > a {
text-decoration: line-through;
}
.wishtitle-declined > a:hover,
.wishtitle-declined > a:focus,
.mw-underline-always .wishtitle-declined > a {
text-decoration: line-through underline;
}
#watchlist-edit-form .wishtitle {
display: inline-block;
}
.mw-search-result-heading > .wishtitle,
.catchangesviewer-table .wishtitle {
display: block;
}
.catchangesviewer-table:has(.wishtitle) {
white-space: wrap;
}`);
let lang = mw.config.get('wgUserLanguage');
let titles;
let loadTitles = async () => {
await mw.loader.using('mediawiki.storage');
titles = titles || mw.storage.getObject('wishtitles');
if (titles?.lang !== lang) {
titles = { lang, w: [], fa: [] };
}
};
let updateTitles = async (crwstatuses, crwcontinue) => {
await mw.loader.using('mediawiki.api');
let params = {
action: 'query',
list: 'communityrequests-wishes',
crwlang: lang,
crwstatuses: crwstatuses,
crwprop: 'title|updated',
crwsort: 'updated',
crwdir: 'ascending',
crwlimit: 'max',
crwcontinue: crwcontinue,
formatversion: 2
};
if (!crwcontinue && !crwstatuses && titles._) {
params.crwcontinue = `|${titles._}|0`;
}
let response = await new mw.Api().get(params);
let wishes = response?.query?.['communityrequests-wishes'];
if (wishes?.length) {
let $span = $('<span>');
wishes.forEach(w => {
let id = w.crwtitle.match(/^Community Wishlist\/W(\d+)/)?.[1];
if (!id) return;
titles.w[id - 1] = $span.html(w.title).text();
if (crwstatuses === 'declined') {
(titles.wd = titles.wd || []).push(id - 1);
}
let faId = w.crfatitle?.match(/^Community Wishlist\/FA(\d+)/)?.[1];
if (!faId) return;
titles.fa[faId - 1] = w.focusareatitle;
});
if (!crwstatuses) {
titles._ = wishes.at(-1).updated.replace(/\D/g, '');
}
}
let expiry = 86400;
if (crwstatuses || crwcontinue) {
let prev = mw.storage.getObject('_EXPIRY_wishtitles');
if (prev) {
expiry = Math.round(Date.now() / 1000) + 86400 - prev;
}
}
mw.storage.setObject('wishtitles', titles, expiry);
crwcontinue = response?.continue?.crwcontinue;
if (crwcontinue) {
await updateTitles(crwstatuses, crwcontinue);
}
};
let getTitle = id => (
id[0] === 'W' ? titles.w[id.slice(1) - 1] : titles.fa[id.slice(2) - 1]
);
let renderTitle = (title, id, tag = 'span') => {
let classes = 'wishtitle';
if (id[0] === 'W' && titles.wd?.includes(id.slice(1) - 1)) {
classes += ' wishtitle-declined';
}
return $(`<${tag}>`).addClass(classes).append(
$('<a>').attr({
href: `/wiki/Community_Wishlist/${id}`,
title: `Community Wishlist/${id}`
}).text(title)
);
};
let callback = ([id, links]) => {
let title = getTitle(id);
if (!title) {
return true;
}
$(links).after(' ', renderTitle(title, id));
};
let selector = '.mw-changeslist-title, ' +
'.mw-changeslist-log-entry > a:not(.mw-userlink), ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize :is(.mw-changeslist-line-inner, .mw-changeslist-line-inner-comment, .mw-enhanced-rc-nested) > .comment > a, ' +
'#watchlist-edit-form .cdx-table td > label > a, ' +
'.mw-search-result-heading > a:not(:has(> .ext-communityrequests-entity-link--label)), ' +
'.mw-contributions-title, ' +
'#mw-whatlinkshere-list li > bdi > a, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-logevent-loglines > li > a, ' +
'#mw-pages li > a, ' +
'.catchangesviewer-table td:nth-child(3) > a';
mw.hook('wikipage.content').add(async $content => {
let links = {};
$content.find('a').each(function () {
if (!this.matches(selector)) return;
let id = this.textContent.match(
/^(?:Talk:|Translations:)?Community Wishlist\/((?:W|FA)\d+)/
)?.[1];
if (!id) return;
(links[id] = links[id] || []).push(this);
});
links = Object.entries(links);
if (!links.length) return;
await loadTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles('declined');
links.forEach(callback);
});
let pn = mw.config.get('wgRelevantPageName');
let id = pn.match(/^(?:Talk:|Translations:)?Community_Wishlist\/((?:W|FA)\d+)/)?.[1];
if (!id) return;
await $.ready;
let extTitle = document.querySelector('.ext-communityrequests-wish--title');
if (extTitle && $('.mw-pt-languages-selected').attr('lang') === lang) return;
await loadTitles();
let title = getTitle(id);
if (!title) {
await updateTitles();
title = getTitle(id);
if (!title) {
await updateTitles('declined');
title = getTitle(id);
if (!title) return;
}
}
let $title = renderTitle(title, id, 'div');
if (mw.config.get('skin') === 'vector-2022') {
$title.prependTo('.vector-page-toolbar');
} else {
$title.insertAfter('#firstHeading');
}
css.textContent += ' .ext-communityrequests-entity-talk-header{display:none}';
if (extTitle) return;
document.title = document.title.replace(
pn.replaceAll('_', ' '),
`${pn.replace(`Community_Wishlist/${id}`, title)} ($&)`
);
})();
mw.config.get('wgWikiID') === 'metawiki' &&
mw.hook('wikipage.watchlistChange').add(async (isWatched, expiry) => {
if (![0, 1].includes(mw.config.get('wgNamespaceNumber'))) return;
let title = mw.config.get('wgTitle');
if (!/^Community Wishlist\/(?:W|FA)\d+$/.test(title)) return;
if (isWatched) {
await new mw.Api().watch(title + '/Votes', expiry);
mw.notify('Watching /Votes too.');
} else {
await new mw.Api().unwatch(title + '/Votes');
mw.notify('Unwatched /Votes too.');
}
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
$(async () => {
let $input = $('#wpTemplateSandboxTemplate');
if (!$input.length) return;
mw.loader.addStyleTag('#templatesandbox-editform .oo-ui-fieldLayout{max-width:50em} #templatesandbox-editform .oo-ui-fieldLayout-field{flex-grow:999}');
let makeTemplateField = () => new OO.ui.FieldLayout(
new mw.widgets.TitleInputWidget({
inputId: 'wpTemplateSandboxTemplate',
name: 'wpTemplateSandboxTemplate',
showMissing: false,
value: $input.val()
}),
{ label: 'Template name:' }
);
if (mw.loader.getState('ext.TemplateSandbox') !== 'registered') {
await mw.loader.using('mediawiki.widgets');
$input.parent().replaceWith(makeTemplateField().$element);
return;
}
let require = await mw.loader.using([
'ext.TemplateSandbox.TemplateSandboxTitleWidget',
'ext.TemplateSandbox.styles', 'jquery.makeCollapsible', 'user.options'
]);
let widget = new (require('ext.TemplateSandbox.TemplateSandboxTitleWidget'))({
$overlay: true,
id: 'wpTemplateSandboxPage',
maxLength: 255,
name: 'wpTemplateSandboxPage',
placeholder: 'Page title',
required: false,
tabIndex: 10,
templateTitleFunc: () => $('#wpTemplateSandboxTemplate').val()
});
widget.$element.attr('data-ooui', '{"_":"mw.widgets.TemplateSandboxTitleWidget"}')
.data('oouiInfused', widget);
let fieldset = new OO.ui.FieldsetLayout({
classes: ['mw-templatesandbox-fieldset', 'mw-collapsed'],
id: 'templatesandbox-editform',
items: [
makeTemplateField(),
new OO.ui.ActionFieldLayout(
widget,
new OO.ui.ButtonInputWidget({
id: 'wpTemplateSandboxPreview',
name: 'wpTemplateSandboxPreview',
label: 'Show preview',
tabIndex: 10,
type: 'submit',
useInputTag: true
}),
{ align: 'top' }
)
],
label: 'Preview page with this template'
});
fieldset.$label.append(' ', $('<span>').addClass('mw-collapsible-toggle-placeholder'));
fieldset.$group.addClass('mw-collapsible-content');
$('#templatesandbox-editform').replaceWith(fieldset.$element.makeCollapsible());
let modules = ['ext.TemplateSandbox'];
if (Number(mw.user.options.get('uselivepreview'))) {
modules.push('ext.TemplateSandbox.preview');
}
mw.loader.load(modules);
});
mw.config.get('wgWikiID') === 'enwiki' &&
mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist' &&
(async () => {
mw.loader.addStyleTag('.xfdnotifier-sublinks::before{content:" ["} .xfdnotifier-sublinks::after{content:"]"} .xfdnotifier-sublinks > span:not(:first-child)::before{content:"\\2009·\\2009"} .mw-portlet.vector-menu[id^="p-xfdnotifier-"] a{display:inline}');
await mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.storage']);
let xfds = [
{
id: 'rm',
label: 'RM',
full: 'Requested moves',
cat: 'Requested moves',
},
{
id: 'rmt',
label: 'RM/T',
full: 'Requested moves (technical)',
page: 'Wikipedia:Requested_moves/Technical_requests',
titleExtractor: $page => (
$page.find(`[data-mw*='"wt":"RMassist/core"']`).closest('li').map(function () {
return this.querySelector('a[rel="mw:WikiLink"]')?.title;
}).get()
)
},
{
id: 'afd',
label: 'AfD',
full: 'Articles for deletion',
cat: 'Articles for deletion'
},
{
id: 'mfd',
label: 'MfD',
full: 'Miscellaneous for deletion',
cat: 'Miscellaneous pages for deletion'
},
{
id: 'tfd',
label: 'TfD',
full: 'Templates for deletion',
cat: 'Templates for deletion'
},
{
id: 'tfm',
label: 'TfM',
full: 'Templates for merging',
cat: 'Templates for merging'
},
{
id: 'cfd',
label: 'CfD',
full: 'Categories for deletion',
cat: 'Categories for deletion'
},
{
id: 'cfr',
label: 'CfR',
full: 'Categories for renaming',
cat: 'Categories for renaming'
},
{
id: 'cfsr',
label: 'CfSR',
full: 'Categories for speedy renaming',
cat: 'Categories for speedy renaming'
},
{
id: 'cfm',
label: 'CfM',
full: 'Categories for merging',
cat: 'Categories for merging'
},
{
id: 'cfs',
label: 'CfS',
full: 'Categories for splitting',
cat: 'Categories for splitting'
},
{
id: 'cfl',
label: 'CfL',
full: 'Categories for listifying',
cat: 'Categories for listifying'
},
{
id: 'cfc',
label: 'CfC',
full: 'Categories for conversion',
cat: 'Categories for conversion'
},
{
id: 'cfgd',
label: 'CfGD',
full: 'Categories for general discussion',
cat: 'Categories for general discussion'
},
{
id: 'ffd',
label: 'FfD',
full: 'Files for discussion',
cat: 'Wikipedia files for discussion'
},
{
id: 'rfd',
label: 'RfD',
full: 'Redirects for discussion',
cat: 'All redirects for discussion'
},
{
id: 'prod',
label: 'PROD',
full: 'Articles proposed for deletion',
cat: 'All articles proposed for deletion'
}
];
window.xfd = xfds;
let queryTitles = async (xfd, titles) => {
if (!titles.length) return;
let response = await new mw.Api().get({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched) {
xfd.pages.push(p.title);
}
});
await queryTitles(xfd, titles.slice(50));
};
let queryPage = async xfd => {
let $page = $($.parseHTML(await $.get(
`https://en.wikipedia.org/w/rest.php/v1/page/${encodeURIComponent(xfd.page)}/html`
)));
await queryTitles(xfd, xfd.titleExtractor($page));
};
let queryCat = async (xfd, gcmcontinue) => {
let response = await new mw.Api().get({
action: 'query',
prop: 'info|categories',
inprop: 'watched',
clprop: 'sortkey',
clcategories: `Category:${xfd.cat}`,
generator: 'categorymembers',
gcmtitle: `Category:${xfd.cat}`,
gcmlimit: 'max',
gcmsort: 'timestamp',
gcmdir: 'older',
gcmcontinue: gcmcontinue,
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched && p.categories?.[0]?.sortkeyprefix !== ' ') {
xfd.pages.push(p.title);
}
});
if (response?.continue?.gcmcontinue) {
await queryCat(xfd, response.continue.gcmcontinue);
}
};
let show = async (xfd, lastId, isCache) => {
if (xfd.portlet && isCache) return;
let portletId = 'p-xfdnotifier-' + xfd.id;
if (xfd.portlet) {
$(xfd.portlet).find('ul').empty();
if (!xfd.pages.length) return;
} else {
await $.ready;
xfd.portlet = mw.util.addPortlet(portletId, xfd.label, '#' + lastId);
}
let $label = $(`#${portletId}-label`).attr('title', xfd.full);
if (xfd.page) {
$label.wrapInner($('<a>').attr('href', mw.util.getUrl(xfd.page)));
}
xfd.pages.forEach(p => {
let t = mw.Title.newFromText(p);
let isTalk = t.isTalkPage();
let $other = $('<a>').attr({
href: t[isTalk ? 'getSubjectPage' : 'getTalkPage']().getUrl(),
title: isTalk ? 'subject' : 'talk'
}).text(isTalk ? 's' : 't');
let link = mw.util.addPortletLink(portletId, t.getUrl(), p).querySelector('a');
$('<span>').addClass('xfdnotifier-sublinks').append(
$('<span>').append($other),
$('<span>').append(
$('<a>').attr({
href: t.getUrl({ action: 'history' }),
title: 'history'
}).text('h')
)
).insertAfter(link);
});
};
mw.hook('wikipage.content').add(mw.util.throttle(async () => {
let cache = mw.storage.getObject('xfdnotifier') || {};
let lastId = 'p-tb';
for (let xfd of xfds) {
let portletId = 'p-xfdnotifier-' + xfd.id;
let now = Math.floor(Date.now() / 1000);
if (now - cache[xfd.id]?.[0] < 600) {
xfd.pages = cache[xfd.id].slice(1);
await show(xfd, lastId, true);
lastId = portletId;
continue;
}
xfd.pages = [];
if (xfd.cat) {
await queryCat(xfd);
} else if (xfd.page) {
await queryPage(xfd);
}
cache[xfd.id] = [now, ...xfd.pages];
mw.storage.setObject('xfdnotifier', cache, 604800);
await show(xfd, lastId);
lastId = portletId;
}
}, 1800000));
})();
26fc73duuzgsfqbb9tbrx312k4e15p7
735817
735816
2026-04-01T11:22:38Z
Nardog
40946
735817
javascript
text/javascript
(async function listTools() {
let pageAction = mw.config.get('wgAction');
let isView = pageAction === 'view';
let isEdit = ['edit', 'submit'].includes(pageAction);
if (!isView && !isEdit) return;
let pageType = mw.config.get('wgCanonicalSpecialPageName') ||
mw.config.get('wgNamespaceNumber');
if (isView && !pageType && !mw.config.exists('wgRedirectedFrom') &&
!mw.config.get('wgIsRedirect') &&
!mw.config.get('wgPageName').includes('/')
) {
return;
}
await mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api',
'mediawiki.interface.helpers.styles'
]);
mw.loader.addStyleTag(`.listtools:not(#mw-content-subtitle .listtools) {
font-size: 85%;
}
.listtools, .listtools a {
font-weight: normal !important;
font-style: normal;
}
.mw-datatable .listtools {
display: block;
}
.listtools + .mw-whatlinkshere-tools,
#watchlist-edit-form .listtools ~ .mw-changeslist-links,
.mw-special-DisambiguationPageLinks .listtools + a {
display: none;
}`);
let messages = Object.assign({
watched: 'Added "$1" to your watchlist',
watchFail: `Couldn't watch "$1"`,
unwatchFail: `Couldn't unwatch "$1"`
}, window.listtoolsMessages);
let getMsg = (key, ...args) => (
Object.hasOwn(messages, key) ? mw.format(messages[key], ...args) : key
);
let notif;
let watchHandler = async function (e) {
e.preventDefault();
let $link = $(this);
let $wrapper = $link.parent();
$link.detach();
let params = new URLSearchParams(this.search);
let action = params.get('action');
$wrapper.text(getMsg(action + 'ing'));
let pn = params.get('title').replaceAll('_', ' ');
let promise = new mw.Api()[action](pn);
if (notif) {
notif.close();
notif = null;
}
try {
let result = await promise;
if (!result || !result[action + 'ed']) throw '';
let newAction = action === 'watch' ? 'unwatch' : 'watch';
params.set('action', newAction);
$link.add(`.listtools-watch > a[href="${this.pathname + this.search}"]`)
.attr('href', this.pathname + '?' + params)
.text(getMsg(newAction));
if (action !== 'watch') return;
let require = await mw.loader.using([
'mediawiki.notification', 'mediawiki.watchstar.widgets'
]);
notif = await mw.notify(
new (require('mediawiki.watchstar.widgets'))('watch', pn, null, $.noop, {
message: getMsg('watched', pn)
}).$element,
{ tag: 'listtools' }
);
} catch {
notif = await mw.notify(getMsg(action + 'Fail', pn), {
tag: 'listtools',
type: 'error'
});
} finally {
$wrapper.html($link);
}
};
let extGetMain = function () {
return this.title;
};
let re = new RegExp(`(?:\\?title=|${
mw.util.escapeRegExp(mw.format(mw.config.get('wgArticlePath'), ''))
})([^#&?]+)`);
let processed = new WeakSet();
let processLinks = ($links, module, titles) => {
let isBatch = !!titles;
titles = titles || new Set();
$links.each(function (i) {
if (processed.has(this)) return;
let $link = $links.eq(i);
let pn;
if (module.useText) {
pn = $link.text();
} else {
let match = $link.attr('href')?.match(re);
if (!match) return;
pn = decodeURIComponent(match[1]);
}
let t = mw.Title.newFromText(pn);
if (!t) return;
if (module.titlesOnly) {
let text = $link.text();
if (text !== pn.replaceAll('_', ' ') &&
(text !== t.getMainText() || t.namespace === 2)
) {
return;
}
}
if ($link.is('.external, .extiw')) {
Object.assign(t, {
getMain: extGetMain,
host: this.host,
namespace: 0,
title: pn
});
} else {
if (t.namespace < 0) return;
if ($link.hasClass('new')) {
t.missing = true;
}
titles.add(t.getSubjectPage().toText());
}
let $tools = $('<span>').addClass('listtools mw-changeslist-links')
.data('listtools', t);
tools.forEach(tool => {
addTool($tools, tool);
});
if ($link.is(':is(del, bdi) > :only-child')) {
if (module.position === 'end') {
$link.parent().parent().append(' ', $tools);
} else {
$link.parent().after(' ', $tools);
}
} else if (module.position === 'end') {
$link.parent().append(' ', $tools);
} else {
$link.after(' ', $tools);
}
if (module.post) {
module.post($tools);
}
processed.add(this);
});
if (!isBatch) {
getWatched(titles);
}
};
let tools = [
{
name: 'edit',
url: t => t.getUrl({ action: 'edit' })
},
{
name: 'hist',
url: t => !t.missing && t.getUrl({ action: 'history' })
},
{
name: 'links',
url: t => mw.util.getUrl('Special:WhatLinksHere/' + t)
},
{
name: 'watch',
url: t => !t.host && t.getSubjectPage().getUrl({ action: 'watch' }),
callback: watchHandler
}
];
let addTool = ($tools, tool, escapedName) => {
let t = $tools.data('listtools');
let $duplicate = escapedName &&
$tools.children('.listtools-' + escapedName);
let url = tool.url;
if (typeof url === 'function') {
url = url(t);
if (!url) {
$duplicate?.remove();
return;
}
}
let $link = $('<a>').attr('href', url).text(getMsg(tool.name));
if (t.host) {
$link.prop('host', t.host);
}
if (tool.callback) {
$link.on('click', tool.callback);
}
let $wrapper = $('<span>').addClass('listtools-' + tool.name)
.append($link);
let $next = tool.next && $tools.children('.listtools-' + tool.next);
if ($next?.length) {
$duplicate?.remove();
$next.before($wrapper);
} else if ($duplicate?.length) {
$duplicate.replaceWith($wrapper);
} else {
$tools.append($wrapper);
}
};
let extend = tool => {
if (tool.label && !Object.hasOwn(messages, tool.label)) {
messages[tool.name] = tool.label;
}
if (tool.next) {
tool.next = $.escapeSelector(tool.next);
}
let existingTool = tools.find(t => t.name === tool.name);
if (existingTool) {
Object.assign(existingTool, tool);
} else {
tools.push(tool);
}
let escapedName = existingTool && $.escapeSelector(tool.name);
let $allTools = $('.listtools');
$allTools.each(function (i) {
addTool($allTools.eq(i), tool, escapedName);
});
};
let getWatched = async titles => {
if (!Array.isArray(titles)) {
titles = [...titles].slice(0, 500);
}
if (!titles.length) return;
(await new mw.Api().post({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages.forEach(page => {
if (!page.watched) return;
$(`.listtools-watch > a[href="${mw.util.getUrl(page.title, { action: 'watch' })}"]`)
.attr('href', mw.util.getUrl(page.title, { action: 'unwatch' }))
.text(getMsg('unwatch'));
});
getWatched(titles.slice(50));
};
mw.hook('listtools.ready').fire(extend);
let catTreeCallback = (records, observer) => {
let $links = $(records[0].target).find('.CategoryTreeItem > bdi > a');
if ($links.length) {
observer.takeRecords();
observer.disconnect();
processLinks($links, catTreeModule);
}
};
let catTreeModule = {
selector: '.CategoryTreeItem > bdi > a',
types: [14, 'CategoryTree'],
position: 'end',
post: $tools => {
$tools.parent().next('.CategoryTreeChildren').each(function () {
new MutationObserver(catTreeCallback)
.observe(this, { childList: true });
});
}
};
let modules = [
{
selector: '#mw-pages li > a, #mw-pages li > span > a',
types: [14]
},
catTreeModule,
{
selector: '#mw-imagepage-section-linkstoimage a, #mw-imagepage-section-globalusage a',
types: [6]
},
{
selector: '#mw-globalusage-result a',
types: ['GlobalUsage']
},
{
selector: '.mw-search-result-heading > a, .searchalttitle > a.mw-redirect, .iw-result__title > a, .mw-search-exists a',
types: ['Search']
},
{
selector: '.mw-search-createlink a',
types: ['Search'],
titlesOnly: true
},
{
selector: '#watchlist-edit-form .cdx-table td > label > a',
types: ['EditWatchlist']
},
{
selector: '.plainlinks > li > a',
types: ['AbuseLog'],
titlesOnly: true
},
{
selector: '#mw-allmessagestable td:first-child > a:first-child:not(.new)',
types: ['Allmessages'],
position: 'end'
},
{
selector: '.mw-spcontent li a',
types: ['DisambiguationPageLinks', 'Listredirects'],
titlesOnly: true
},
{
selector: 'li > a:first-child',
types: ['FileDuplicateSearch']
},
{
selector: '.TablePager_col_title > a:first-child, .TablePager_col_template > a',
types: ['LintErrors'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: 'form > ul > li > a',
types: ['Nuke'],
position: 'end',
titlesOnly: true
},
{
selector: '.page-assessments a',
types: ['PageAssessments'],
titlesOnly: true
},
{
selector: '.TablePager_col_pr_page > a',
types: ['Protectedpages'],
position: 'end'
},
{
selector: '#mw-content-text > ul a',
types: ['Protectedtitles'],
position: 'end'
},
{
selector: '.mw-fr-pending-changes-page-title',
types: ['PendingChanges'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: '#mw-content-text > ul a:first-child',
types: ['StablePages'],
position: 'end'
},
{
selector: '.TablePager_col__page a',
types: ['TopicSubscriptions']
},
{
selector: '.undeleteResult > a',
types: ['Undelete'],
position: 'end',
useText: true
},
{
selector: '.TablePager_col_img_name > a:first-child',
// types: ['Listfiles'],
position: 'end'
},
{
selector: '.mw-newpages-pagename',
post: $tools => {
let $contents = $tools.parent().contents();
$contents.slice(
$contents.index($tools) + 1,
$contents.index($contents.filter('.mw-newpages-length'))
).replaceWith(' ');
}
},
{
selector: '#mw-whatlinkshere-list li > bdi > a'
},
{
selector: '.mw-changeslist-log-entry > a:not(.mw-changeslist-log-gblblock a, .mw-changeslist-log-globalauth a)',
titlesOnly: true
},
{
selector: '.mw-logevent-loglines > li:not(.mw-logline-gblblock, .mw-logline-globalauth) > a',
types: ['Log'],
titlesOnly: true
},
{
selector: '#mw-diff-otitle1 > strong > a, #mw-diff-ntitle1 > strong > a',
types: ['ComparePages'],
position: 'end'
},
{
selector: '#movepage-oldlink, #movepage-newlink',
types: ['Movepage']
},
{
selector: '.mw-undelete-revision a:not(.mw-userlink, .mw-usertoollinks > a)',
types: ['Undelete'],
useText: true
},
{
selector: '.galleryfilename, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner-comment > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-enhanced-rc-nested > .comment > a'
},
{
selector: '.mw-spcontent li a',
position: 'end',
titlesOnly: true
}
];
if (isEdit) {
let post = $tools => {
if (!$tools[0].closest('.templatesUsed')) return;
$tools.parent().contents().last().each(function () {
this.textContent = this.textContent.slice(1);
}).end().slice(-3, -1).remove();
};
let callback = mw.util.debounce(() => {
processLinks(
$('.mw-editfooter-list a, #wikiPreview > .previewnote a'),
{ titlesOnly: true, post }
);
}, 500);
mw.hook('wikipage.editform').add($form => {
callback();
$form.find('.templatesUsed').each(function () {
if (processed.has(this)) return;
processed.add(this);
new MutationObserver(callback)
.observe(this, { childList: true, subtree: true });
});
});
} else if (typeof pageType === 'number') {
$(() => {
processLinks($('.subpages a, .mw-redirectedfrom a, .redirectText a'), {});
});
}
mw.hook('wikipage.content').add($content => {
let titles = new Set();
let $links = $content.find('a');
modules.forEach(module => {
if (module.types && !module.types.includes(pageType)) return;
processLinks($links.filter(module.selector), module, titles);
});
getWatched(titles);
});
}());
mw.hook('listtools.ready').add(extend => {
// extend({
// name: 'talk',
// url: t => !t.isTalkPage() && t.canHaveTalkPage() && t.getTalkPage().getUrl(),
// next: 'hist'
// });
extend({
name: 'subject',
url: t => t.isTalkPage() && t.getSubjectPage().getUrl(),
next: 'hist'
});
extend({
name: 'last',
url: t => !t.missing && t.getUrl({ diff: 'cur', diffonly: 1 }),
next: 'links'
});
// extend({
// name: 'purge',
// url: t => t.getUrl({ action: 'purge' }),
// next: 'watch',
// callback: function (e) {
// e.preventDefault();
// let $link = $(this);
// let $wrapper = $link.parent();
// $link.detach();
// $wrapper.text('purging');
// let pn = $wrapper.closest('.listtools').data('listtools').toText();
// new mw.Api().post({
// action: 'purge',
// forcelinkupdate: 1,
// titles: pn,
// formatversion: 2
// }).then(response => {
// if (response.purge[0].purged) {
// mw.notify(`Purged "${pn}"'`);
// }
// }).always(() => {
// $wrapper.html($link);
// });
// }
// });
extend({
name: 'copy',
url: '#',
callback: function (e) {
e.preventDefault();
let text = $(this).closest('.listtools').data('listtools').toText();
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch (err) {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
}
});
});
(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
mw.config.get('wgCanonicalSpecialPageName') !== 'GlobalContributions' &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector += ', ' + this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i + 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i + 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes += ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i + '/' + count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 + ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 + ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());
if (mw.config.get('wgNamespaceNumber') === 14 && (
mw.config.get('wgAction') === 'view' || !mw.config.get('wgArticleId')
)) {
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox8.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.DateFormatter',
'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget', 'mediawiki.widgets.datetime',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-movement',
'mediawiki.interface.helpers.styles', 'user.options'
]);
}
$(function moveHistory() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Move history', 't-movehistory').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.moveHistoryDialog) {
window.moveHistoryDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox5.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.Title', 'mediawiki.DateFormatter',
'oojs-ui-windows', 'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.DateInputWidget', 'oojs-ui.styles.icons-interactions',
'mediawiki.interface.helpers.styles'
]);
});
});
});
$(function sectionSearch() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Section search', 't-sectionsearch').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.sectionSearchDialog) {
window.sectionSearchDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox7.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-windows',
'mediawiki.widgets', 'mediawiki.widgets.NamespacesMultiselectWidget'
]);
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'CentralAuth' &&
mw.loader.using('jquery.tablesorter', function sortCentralAuthByEditCount() {
mw.hook('wikipage.content').add($content => {
let $table = $content.find('.mw-centralauth-wikislist').has('td');
if (!$table.length) return;
$table.tablesorter().data('tablesorter').sort([{ 4: 'desc' }, { 1: 'asc' }]);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
[10, 828].includes(mw.config.get('wgNamespaceNumber')) &&
!mw.config.get('wgTitle').endsWith('/doc') &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/AutoTestcases.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/TemplatePreviewGuard.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// $(function templatePreviewGuard() {
// let button = document.querySelector('input[name="wpTemplateSandboxPreview"]');
// if (!button) return;
// let proceed;
// button.addEventListener('click', e => {
// if (proceed) {
// proceed = false;
// return;
// }
// e.preventDefault();
// e.stopPropagation();
// let formData = new FormData(button.form);
// let page = formData.get('wpTemplateSandboxPage');
// let temp = formData.get('wpTemplateSandboxTemplate');
// if (!page || !temp) return;
// mw.loader.using('mediawiki.api').then(() => (
// new mw.Api().get({
// action: 'query',
// titles: page,
// prop: 'templates',
// tltemplates: temp,
// formatversion: 2
// })
// )).always(response => {
// if (((((response || {}).query || {}).pages || [])[0] || {}).templates ||
// confirm(`"${page}" doesn't appear to transclude "${temp}". Continue?`)
// ) {
// proceed = true;
// button.click();
// }
// });
// }, true);
// if (!mw.config.get('wgArticleId')) return;
// let widgetEl = document.querySelector('#wpTemplateSandboxPage.oo-ui-widget');
// if (!widgetEl) return;
// let pn = mw.config.get('wgPageName').replace(/_/g, ' ');
// mw.loader.using(['mediawiki.api', 'oojs-ui-core']).then(() => (
// new mw.Api().get({
// action: 'query',
// titles: pn,
// prop: 'transcludedin',
// tiprop: 'title',
// tilimit: 'max',
// formatversion: 2
// })
// )).then(response => {
// if (!response.batchcomplete) return;
// let pages = response.query.pages[0].transcludedin
// .filter(o => o.title !== pn);
// if (!pages.length) return;
// let widget = OO.ui.infuse(widgetEl);
// if (pages.length === 1) {
// widget.setValue(pages[0].title);
// return;
// }
// widget.$element.replaceWith(
// new OO.ui.ComboBoxInputWidget({
// id: 'wpTemplateSandboxPage',
// maxlength: widget.$input.prop('maxLength'),
// name: widget.$input.prop('name'),
// options: pages
// .sort((a, b) => a.ns - b.ns || -(a.title < b.title))
// .map(o => ({ data: o.title })),
// placeholder: widget.$input.prop('placeholder'),
// tabIndex: widget.getTabIndex(),
// value: widget.getValue()
// }).on('enter', e => {
// e.preventDefault();
// button.click();
// }).$element
// );
// });
// });
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(async () => {
let form = document.getElementById('editform');
if (!form) return;
let formData = new FormData(form);
let section = formData.get('wpSection');
if (section === 'new') return;
let widget = document.getElementById('wpSummaryWidget');
if (!widget) return;
let isOld = formData.get('altBaseRevId') > 0 ||
(formData.get('baseRevId') || formData.get('parentRevId')) !== formData.get('editRevId');
await mw.loader.using([
'jquery.textSelection', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core',
'oojs-ui.styles.icons-editing-core'
]);
let $textarea = $('#wpTextbox1');
let input = OO.ui.infuse(widget);
let button = new OO.ui.ButtonWidget({
framed: false,
icon: 'undo',
classes: ['autosectionlink-button'],
invisibleLabel: true,
label: 'Restore previous section link'
}).toggle().on('click', () => {
let cache = button.getData();
input.setValue(input.getValue().replace(
/^(\/\*.*?\*\/)?\s*/,
cache[0] ? '/* ' + cache[0] + ' */ ' : ''
));
updatePreview(cache[0]);
cache.reverse();
}).on('toggle', () => {
input.$input.css('width', `calc(100% - ${button.$element.width()}px)`);
});
input.$input.after(button.$element);
let update = mw.util.debounce($diff => {
let lines = $textarea.textSelection('getContents').replace(/\s+$/, '').split('\n');
let firstLineNum;
if (isOld) {
let i, lastLineNum;
$diff.find('td:last-child').each(function () {
if (this.classList.contains('diff-lineno')) {
i = this.textContent.replace(/\D+/g, '') - 1;
} else if (this.classList.contains('diff-context')) {
i++;
} else if (this.classList.contains('diff-addedline')) {
i++;
if (!firstLineNum) {
firstLineNum = i;
}
lastLineNum = i;
} else if (this.classList.contains('diff-empty')) {
if (!firstLineNum) {
firstLineNum = i === 0 ? 1 : i;
}
lastLineNum = i;
}
});
lines.length = lastLineNum || 0;
} else {
let origLines = $textarea.prop('defaultValue').replace(/\s+$/, '').split('\n');
firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
if (!firstLineNum) {
firstLineNum = lines.length < origLines.length
? lines.length
: 1;
}
for (let i = 1, x = lines.length, y = origLines.length;
(section ? i < x : i <= x) && lines[x - i] === origLines[y - i];
i++
) {
lines.pop();
}
}
let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 7;
lines.slice(firstLineNum).forEach(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
lowest = match[1].length;
}
});
let head;
lines.slice(0, firstLineNum).reverse().some(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
head = match[2];
return true;
}
});
if (head) {
head = head
.replace(/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
.replace(/''(.+?)''/g, '$1')
.trim();
} else if (typeof firstLineNum === 'number' && section < 1 && lowest === 7) {
head = '';
}
let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
let prev = match[1];
if (prev === head) return;
input.setValue((typeof head === 'string' ? '/* ' + head + ' */ ' : '') + match[2]);
button.setData([prev, head]).toggle(true);
updatePreview(head);
}, 500);
let updatePreview = head => {
let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
if (!$preview.length) return;
let hasHead = typeof head === 'string';
let url = hasHead && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
let text = hasHead && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + (head || mw.messages.get('autocomment-top', '(top)'));
let $ac = $preview.children('.autocomment:first-child');
if ($ac.length && !$ac[0].previousSibling) {
if (hasHead) {
$ac.children('a').attr('href', url).text(text);
} else {
let node = $ac[0].nextSibling;
if (node?.nodeType === 3) {
node.textContent = node.textContent.replace(/^\s+/, '');
}
$ac.remove();
}
} else if (hasHead) {
$('<span>').addClass('autocomment').append(
$('<a>').attr({
href: url,
title: mw.config.get('wgPageName').replace(/_/g, ' ')
}).text(text),
mw.messages.get('colon-separator', ': ')
).prependTo($preview);
}
};
if (isOld) {
mw.hook('wikipage.diff').add(update);
} else {
$textarea.on('input', update);
mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
if (on && $codeMirror[0].CodeMirror) {
$codeMirror[0].CodeMirror.on('change', update);
}
});
mw.hook('ext.CodeMirror.input').add(update);
update();
}
new mw.Api().loadMessagesIfMissing(['autocomment-top', 'colon-separator']);
mw.loader.addStyleTag('.autosectionlink-button{position:absolute;top:0;right:0;margin:0}');
});
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(function copyRevId() {
let handler = function (e) {
e.preventDefault();
let text = this.closest('.diff td')?.querySelector('[data-mw-revid]')?.dataset.mwRevid ||
this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!text) return;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
document.execCommand('copy');
$input.remove();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id')
)
);
});
}());
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(() => {
let handler = async function (e) {
e.preventDefault();
let td = this.closest('.diff td');
let rev = td
? td.querySelector('[data-mw-revid]')?.dataset.mwRevid
: this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!rev) {
mw.notify(`Couldn't get the revision.`, {
tag: 'markasunseen',
type: 'error'
});
return;
}
let pn = td
? new URLSearchParams([...td.querySelectorAll('a')].pop()?.search).get('title')
: mw.config.get('wgPageName');
if (!pn) return;
await mw.loader.using('mediawiki.api');
let result = (await new mw.Api().postWithEditToken({
action: 'setnotificationtimestamp',
[td ? 'newerthanrevid' : 'torevid']: rev,
titles: pn,
formatversion: 2
})).setnotificationtimestamp?.[0];
if (Object.hasOwn(result, 'notificationtimestamp')) {
mw.notify(`Marked revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'success'
});
} else if (result?.notwatched) {
mw.notify('This page is not on your watchlist.', {
tag: 'markasunseen',
type: 'warn'
});
} else {
mw.notify(`Couldn't mark revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'error'
});
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions after this one as unseen'
}).on('click', handler).text('unseen'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions since this one as unseen'
}).on('click', handler).text('unseen')
)
);
});
})();
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
((mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4) ||
(mw.config.get('wgWikiID') === 'metawiki' && mw.config.get('wgPageContentModel') === 'wikitext')) &&
mw.loader.using(['mediawiki.util', 'mediawiki.Title'], function copyUnsig() {
let handler = function (e) {
e.preventDefault();
let parent = this.closest('li, td');
let ts = parent.textContent.match(/\d\d:\d\d, \d\d? [A-Z][a-z]+ \d{4}/)?.[0];
if (!ts) return;
let user = parent.querySelector('.mw-userlink').textContent;
if (mw.util.isIPv6Address(user)) {
user = user.toUpperCase();
}
let temp = mw.util.isIPAddress(user) ? 'unsigned IP' : 'unsigned';
let text = `{{subst:${temp}|${user}|${ts}}}`;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').filter(function () {
if (mw.config.get('wgWikiID') === 'metawiki') {
return true;
}
let link = this.querySelector('strong > a') ||
this.parentElement.querySelector('#differences-prevlink, #differences-nextlink');
if (!link) return;
let t = mw.Title.newFromText(mw.util.getParamValue('title', link.search));
return t.isTalkPage() || t.namespace === 4;
}).append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig')
)
);
});
});
// mw.config.get('wgAction') === 'history' &&
// mw.loader.using('mediawiki.util', function () {
// mw.hook('wikipage.content').add($content => {
// $content.find('a.mw-changeslist-date').after(function () {
// return [
// ' (',
// $('<a>').attr('href', mw.util.getUrl(null, {
// action: 'edit',
// oldid: this.closest('li').dataset.mwRevid
// })).text('e'),
// ')'
// ];
// });
// });
// });
// ['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
// mw.hook('wikipage.content').add($content => {
// $content.find('.mw-changeslist-history').parent().after(function () {
// return $('<span>').append(
// $('<a>').attr(
// 'href',
// this.firstElementChild.getAttribute('href').slice(0, -7) + 'edit'
// ).text('e')
// );
// });
// });
if (screen.width < 500) {
mw.loader.addStyleTag('@font-face{font-family:CharisW;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/017b2b2ad86e09d3c22b8cf0dfc78247/CharisSILRegular.ttf) format(truetype)} @font-face{font-family:CharisW;font-weight:700;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/6f5069ac6a300dad45383c952e92c573/CharisSILBold.ttf) format(truetype)} body .IPA{font-family:CharisW,sans-serif} .mw-highlight-lines > pre{width:120em}');
location.hash && $(() => {
let target = document.querySelector(':target');
if (target?.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
});
}
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
(mw.config.exists('wgCodeEditorCurrentLanguage') ||
mw.config.exists('cmMode') && mw.config.get('cmMode') !== 'mediawiki') &&
(function saveNEdit() {
let notif;
$(document.body).on('click', '#wpSave', async function (e) {
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey ||
e.originalEvent?.defaultPrevented
) {
return;
}
e.preventDefault();
await mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'jquery.textSelection', 'oojs-ui-core'
]);
let button = OO.ui.infuse(this.parentElement).setDisabled(true);
let $textarea = $('#wpTextbox1');
let text = $textarea.textSelection('getContents');
let $summary = $('#wpSummary');
let formData = new FormData(this.form);
let promise = new mw.Api().postWithEditToken({
action: 'edit',
title: mw.config.get('wgPageName'),
text: text,
section: formData.get('wpSection') || undefined,
summary: $summary.textSelection('getContents'),
[$('#wpMinoredit').prop('checked') ? 'minor' : 'notminor']: 1,
baserevid: formData.get('editRevId'),
basetimestamp: formData.get('wpEdittime'),
starttimestamp: formData.get('wpStarttime'),
watchlist: $('#wpWatchthis').prop('checked') ? 'watch' : 'unwatch',
watchlistexpiry: formData.get('wpWatchlistExpiry') || undefined,
undo: formData.get('wpUndidRevision') || undefined,
undoafter: formData.get('wpUndoAfter') || undefined,
contentformat: formData.get('format'),
contentmodel: formData.get('model'),
assertuser: mw.config.get('wgUserName'),
formatversion: 2
});
notif?.close();
notif = null;
try {
let response = await promise;
if (response?.edit?.result !== 'Success') throw '';
$('#editform > input[name="wpUndidRevision"], #editform > input[name="wpUndoAfter"]').remove();
$textarea.data('origtext', text).prop('defaultValue', text);
$summary.val($summary.prop('defaultValue'));
if (mw.loader.getState('mediawiki.editRecovery.edit') === 'ready') {
let storage = mw.loader.moduleRegistry['mediawiki.editRecovery.edit'].packageExports['storage.js'];
storage.deleteData(mw.config.get('wgPageName'));
storage.closeDatabase();
}
notif = await mw.notify(response.edit.nochange ? 'No change' : [
document.createTextNode('Saved'),
$('<p>').append(
new OO.ui.ButtonWidget({
href: mw.util.getUrl(),
target: '_blank',
label: 'View'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, {
diff: response.edit.newrevid || 'cur',
diffonly: 1
}),
target: '_blank',
label: 'Diff'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, { action: 'history' }),
target: '_blank',
label: 'History'
}).$element
)[0]
], { tag: 'savenedit' });
} catch (error) {
notif = await mw.notify(error?.error?.info || error || 'Save failed', {
autoHideSeconds: 'long',
tag: 'savenedit',
type: 'error'
});
} finally {
button.setDisabled();
}
});
}());
mw.config.get('wgNamespaceNumber') === 0 &&
mw.config.get('wgAction') === 'view' &&
mw.config.get('wgCategories')?.some(c => c.endsWith(' actors') || c.endsWith(' actresses')) &&
$(() => {
let n = $.escapeSelector(mw.config.get('wgTitle').replace(/ \(.+\)$/, ''));
let $links = $(`.hatnote a[title$="${n} filmography"], .hatnote a[title*="${n} on "], .hatnote a[title*="${n} performances"]`);
if (!$links.length) return;
let titles = {};
$links = $links.filter(function () {
let text = this.textContent;
return !(titles[text] = Object.hasOwn(titles, text));
});
mw.notify(
$links.length === 1
? $links.clone()
: $('<ul>').append($links.clone().wrap('<li>').parent()),
{ autoHideSeconds: 'long' }
);
});
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
let os = mw.user.options.get('userjs-rcmuter');
let set = new Set(os && os.split('|'));
let save = () => {
let ns = [...set].join('|');
if (ns === mw.user.options.get('userjs-rcmuter')) return;
new mw.Api().saveOption('userjs-rcmuter', ns);
mw.user.options.set('userjs-rcmuter', ns);
$edit.attr('data-rcmuter', set.size);
};
mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
let $edit = $('<a>').attr({
class: 'rcmuter-edit',
href: '#',
'data-rcmuter': set.size
}).text('Edit muted').on('click', e => {
e.preventDefault();
mw.loader.using([
'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
let multiselect = new mw.widgets.UsersMultiselectWidget({
$overlay: dialog.$overlay,
ipAllowed: true,
selected: [...set]
}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
let instance = dialog.open({
message: $([
document.createTextNode('Muted users:'),
multiselect.$element[0]
]),
size: 'medium'
});
instance.opened.then(() => {
setTimeout(() => {
multiselect.focus().menu.toggle(false);
});
});
instance.closed.then(result => {
if (!result || result.action !== 'accept') return;
set = new Set(multiselect.getSelectedUsernames());
save();
mw.notify('Changes will take effect in next load.', {
tag: 'rcmuter'
});
});
});
});
let buttonsShown;
let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
e.preventDefault();
if (buttonsShown) {
mw.hook('wikipage.content').remove(addButtons);
$('.rcmuter-toggle').remove();
this.textContent = 'Show toggle buttons';
} else {
mw.hook('wikipage.content').add(addButtons);
this.textContent = 'Hide toggle buttons';
}
buttonsShown = !buttonsShown;
});
let $toggle = $('<a>').attr({
class: 'rcmuter-togglemuted',
href: '#'
}).text('Show muted').on('click', function (e) {
e.preventDefault();
this.textContent = document.body.classList.toggle('rcmuter-disabled')
? 'Hide muted'
: 'Show muted';
});
let $toggleSpan = $('<span>').hide().append($toggle);
mw.util.addSubtitle(
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append($edit),
$('<span>').append($toggleButtons),
$toggleSpan
)[0]
);
let toggle = function (e) {
e.preventDefault();
let user = $(this)
.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
.last().text().trim();
if (!user) {
mw.notify(`Can't retrieve the username.`, {
tag: 'rcmuter',
type: 'error'
});
return;
}
let muting = this.parentElement.classList.toggle('rcmuter-unmute');
set[muting ? 'add' : 'delete'](user);
save();
this.textContent = muting ? 'unmute' : 'mute';
mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
tag: 'rcmuter'
});
};
let addButtons = $content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) {
$content = $('#mw-content-text');
if ($content.has('.rcmuter-toggle').length) return;
}
let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
let $muted = $tools.filter('.rcmuter-muted *');
$tools.not($muted).append(
$('<span>').addClass('rcmuter-toggle').append(
$('<a>').attr('href', '#').text('mute').on('click', toggle)
)
);
if (!$muted.length) return;
$muted.append(
$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
$('<a>').attr('href', '#').text('unmute').on('click', toggle)
)
);
};
let mutedCount;
let filter = function () {
let muted = set.has(this.textContent);
if (muted) mutedCount++;
return muted;
};
mw.hook('wikipage.content').add($content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) return;
if (!set.size) {
$toggleSpan.hide();
return;
}
mutedCount = 0;
$content.find('.changedby > .mw-userlink:only-child')
.filter(filter).closest('table').addClass('rcmuter-muted');
$content.find('.mw-userlink:not(.changedby > *, .comment *, .rcmuter-muted *)')
.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
$toggleSpan.toggle(!!mutedCount);
$toggle.attr('data-rcmuter', mutedCount);
});
});
location.hostname.endsWith('.wikipedia.org') &&
mw.config.get('wgNamespaceNumber') % 2 === 0 &&
// mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.util')).then(function refRenamer() {
if (!document.getElementById('p-tb')) return;
let messages = Object.assign({
portlet: 'RefRenamer',
loading: 'Loading RefRenamer...'
}, window.refrenamerMessages);
let clicked;
mw.util.addPortletLink('p-tb', '#', messages.portlet, 't-refrenamer').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.refRenamer) {
window.refRenamer();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox6.js&action=raw&ctype=text/javascript');
mw.notify(messages.loading, {
autoHideSeconds: 'long',
tag: 'refrenamer'
});
});
});
if (['edit', 'submit'].includes(mw.config.get('wgAction'))) {
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/ExpandContractions.js&action=raw&ctype=text/javascript', 's');
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/Unpipe.js&action=raw&ctype=text/javascript', 's');
}
mw.config.get('wgAction') !== 'history' &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/CopyCodeBlock.js&action=raw&ctype=text/javascript', 's');
mw.config.exists('wgDiffNewId') &&
mw.config.get('wgDiscussionToolsFeaturesEnabled') &&
(function () {
let data = {}, clickHandler, autoClear, run;
window.dtc = data;
let highlight = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
mw.loader.moduleRegistry['ext.discussionTools.init'].packageExports['highlighter.js']
.highlightNewComments(mw.dt.pageThreads, true, ids);
if (clickHandler) {
$(document.body).off('click', clickHandler);
return;
}
$._data(document.body, 'events').click.some(o => {
if (String(o.handler).includes('highlighter.clearHighlightTargetComment(')) {
$(document.body).off('click', o.handler);
clickHandler = o.handler;
return true;
}
});
$._data(window, 'events').popstate.some(o => {
if (String(o.handler).includes('highlighter.highlightTargetComment(')) {
$(window).off('popstate', o.handler);
return true;
}
});
};
let scroll = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
let yToSpan = Object.fromEntries(
ids.map(id => document.getElementById(id)).filter(Boolean)
.map(span => [span.getBoundingClientRect().y, span])
);
let ys = Object.keys(yToSpan);
if (!ys.length) return;
let lower = ys.filter(y => y > 10);
if (!lower.length ||
Math.max(...lower) < document.documentElement.clientHeight
) {
yToSpan[Math.min(...ys)].scrollIntoView();
} else {
yToSpan[Math.min(...lower)].scrollIntoView();
}
};
let scrollToNext = function (e) {
e.preventDefault();
let revId = mw.config.get('wgDiffOldId');
if (!revId || !data[revId]) return;
let i = data[revId].indexOf(
this.closest('[data-mw-thread-id]').dataset.mwThreadId
);
if (i === -1) return;
let next = data[revId][i + 1] || data[revId][0];
document.getElementById(next).scrollIntoView();
};
mw.hook('wikipage.content').add(async $content => {
let revId = mw.config.get('wgDiffOldId');
if (!revId) return;
let param = new URLSearchParams(location.search).get('diffonly');
if (param && param !== '0') return;
if (data[revId]) {
highlight(revId);
return;
}
await mw.loader.using(['ext.discussionTools.init', 'mediawiki.util']);
let begin = Date.parse($('#mw-diff-otitle1 .mw-diff-timestamp').data('timestamp'));
data[revId] = mw.dt.pageThreads.getCommentItems()
.filter(c => c.timestamp > begin).map(c => c.id);
if (!data[revId].length) return;
await new Promise(setTimeout);
highlight(revId);
$content.find('.ext-discussiontools-init-replylink-buttons').filter(function () {
return data[revId].includes(this.dataset.mwThreadId);
}).children('span:last-of-type').before(
' | ',
$('<a>').attr({
href: '#',
role: 'button'
}).text('next').on('click', scrollToNext)
);
if (run || !document.getElementById('p-tb')) return;
run = true;
let portlet = mw.util.addPortletLink('p-tb', '#', 'Scroll to next', 't-scrolltonext');
portlet.firstElementChild.addEventListener('click', e => {
e.preventDefault();
scroll(mw.config.get('wgDiffOldId'));
});
mw.util.addPortletLink('p-tb', '#', 'Toggle highlight', 't-togglehighlight').firstElementChild.addEventListener('click', e => {
e.preventDefault();
autoClear = !autoClear;
if (autoClear) {
$(document.body).on('click', clickHandler)[0].click();
} else {
highlight(mw.config.get('wgDiffOldId'));
}
});
mw.loader.addStyleTag(`#t-scrolltonext{position:fixed;bottom:${portlet.clientHeight}px} #t-togglehighlight{position:fixed;bottom:0}`);
});
}());
mw.config.get('wgNamespaceNumber') === 6 &&
mw.config.get('wgAction') === 'view' &&
mw.hook('wikipage.content').add($content => {
$content.find('.filehistory .mw-usertoollinks-contribs').after(function () {
return [
' | ',
$('<a>').attr('href', `${
mw.config.get('wgScript')
}?title=Special:ListFiles/${
this.pathname.replace(/^.+\//, '')
}&ilshowall=1`).text('uploads')
];
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function () {
if (!$('input[name="wpSection"]').val()) return;
mw.hook('wikipage.content').add(async $content => {
let $refs = $content.find('.mw-ext-cite-warning-sectionpreview_no_text');
if (!$refs.length) return;
let ids = {};
$refs.each(function () {
ids[this.closest('[id]').id.replace(/-\d+$/, '')] = this;
});
let response = await $.get(`/api/rest_v1/page/html/${encodeURIComponent(mw.config.get('wgPageName'))}`);
$($.parseHTML(response)).find('.mw-reference-text').each(function () {
ids[this.id.replace(/^mw-reference-text-|-\d+$/g, '')]?.replaceWith(this);
});
});
});
mw.hook('moremenu.ready').add(config => {
$('#mm-page-purge-cache > a').on('click', e => {
e.preventDefault();
new mw.Api().post({
action: 'purge',
forcelinkupdate: 1,
titles: config.page.name,
formatversion: 2
}).then(() => {
location.href = mw.util.getUrl();
});
});
$('#mm-page-search-search-history-wikiblame > a').on('click', function (e) {
e.preventDefault();
let q = prompt();
if (q === null) return;
let href = this.href;
if (q) {
let removal = q[0] === '!';
if (removal) {
q = q.slice(1);
}
href += '&needle=' + encodeURIComponent(q);
if (removal) {
href += '&binary_search_inverse=on';
}
href += '&force_wikitags=on';
}
open(href, '_blank');
});
$('#mm-page-expand-templates > a').on('click auxclick', function (e) {
if (e.which > 2) return;
e.preventDefault();
let revId = mw.config.get('wgRevisionId') || Number($('input[name=oldid]').val());
let url = revId
? '/w/rest.php/v1/revision/' + revId
: '/w/rest.php/v1/page/' + config.page.encodedName;
$.get(url).then(response => {
$('<form>').attr({
method: 'post',
action: this.href,
target: '_blank'
}).append(
[
['wpInput', response.source],
['wpContextTitle', config.page.name],
['wpRemoveComments', 1]
].map(([n, v]) => $('<input>').attr({
name: n,
type: 'hidden'
}).val(v))
).appendTo(document.body).trigger('submit').remove();
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'ApiSandbox' &&
mw.hook('apisandbox.formatRequest').add((...args) => {
args[4].complete = function () {
setTimeout(() => {
mw.hook('wikipage.content').fire($('.oo-ui-pageLayout-active'));
}, 100);
};
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.storage')).then(async () => {
let infuseAndCall = (query, method, ...args) => {
let $widget = $(query);
if ($widget.length) {
return OO.ui.infuse($widget)[method](...args);
}
};
let section = $('input[name="wpSection"]').val();
if (section) {
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let save = () => {
let newSource = $textarea.textSelection('getContents');
if (newSource === source) {
mw.storage.session.remove('editfullpage');
} else {
mw.storage.session.setObject('editfullpage', [
mw.config.get('wgPageName'),
section,
newSource.trimEnd(),
infuseAndCall('#wpSummaryWidget', 'getValue') || '',
Number(infuseAndCall('#wpMinoreditWidget', 'isSelected')) || 0,
Number(infuseAndCall('#wpWatchthisWidget', 'isSelected')) || 0,
infuseAndCall('#wpWatchlistExpiryWidget', 'getValue') || 'infinite'
]);
}
};
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
setInterval(() => {
mw.requestIdleCallback(save);
}, 3000);
window.addEventListener('beforeunload', save);
return;
}
let data = mw.storage.session.getObject('editfullpage');
mw.storage.session.remove('editfullpage');
console.log(data);
if (!data || data[0] !== mw.config.get('wgPageName')) return;
let isNew = data[1] === 'new';
let isLead = data[1] === '0';
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let newSource, start, msg, notifOpts = { autoHideSeconds: 'long' };
let orig = [];
if (isNew) {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
newSource = source + (data[3] ? '\n== ' + data[3] + ' ==\n\n' : '\n') + data[2] + '\n';
start = source.length;
} else {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core', 'mediawiki.api']);
let { parse } = await new mw.Api().get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
wrapoutputclass: '',
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
formatversion: 2
});
let target = !isLead && parse.sections.find(s => s.index === data[1]);
if (isLead || target) {
let next = parse.sections.find(s => s.index - 1 === Number(data[1]));
newSource = (isLead ? '' : [...source].slice(0, target.byteoffset)).join('') +
data[2] + (next ? '\n\n' + [...source].slice(next.byteoffset).join('') : '\n');
start = isLead ? 0 : target.byteoffset;
} else {
newSource = source + '\n\n' + data[2] + '\n';
start = source.length;
msg = `Section restored. Couldn't find the section. The source is appended at bottom.`;
notifOpts.type = 'warn';
}
orig[0] = infuseAndCall('#wpSummaryWidget', 'getValue');
infuseAndCall('#wpSummaryWidget', 'setValue', data[3]);
}
$textarea.textSelection('setContents', newSource);
orig[1] = infuseAndCall('#wpMinoreditWidget', 'getSelected');
infuseAndCall('#wpMinoreditWidget', 'setSelected', data[4]);
orig[2] = infuseAndCall('#wpWatchthisWidget', 'getSelected');
infuseAndCall('#wpWatchthisWidget', 'setSelected', data[5]);
orig[3] = infuseAndCall('#wpWatchlistExpiryWidget', 'getValue');
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', data[6]);
setTimeout(() => {
$textarea.textSelection('setSelection', { start });
});
let notif = await mw.notify($([
document.createTextNode(msg || 'Section restored.'),
$('<p>').append(
new OO.ui.ButtonWidget({
flags: 'destructive',
label: 'Discard'
}).on('click', () => {
$textarea.textSelection('setContents', source);
if (orig[0]) {
infuseAndCall('#wpSummaryWidget', 'setValue', orig[0]);
}
infuseAndCall('#wpMinoreditWidget', 'setSelected', orig[1]);
infuseAndCall('#wpWatchthisWidget', 'setSelected', orig[2]);
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', orig[3]);
notif.close();
}).$element
)[0]
]), notifOpts);
});
mw.config.exists('wgPostEdit') &&
mw.loader.using('mediawiki.storage', () => {
mw.storage.session.remove('editfullpage');
});
mw.config.get('wgAction') === 'history' &&
mw.hook('wikipage.content').add(async $content => {
if (!$content.has('.mw-history-line-updated').length) return;
let href = $content.find('a.mw-history-histlinks-current:not(.mw-history-line-updated a)').attr('href');
if (!href) {
await mw.loader.using(['mediawiki.api', 'mediawiki.util']);
let page = (await new mw.Api().get({
action: 'query',
titles: mw.config.get('wgPageName'),
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev >= page.lastrevid) return;
href = mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
}
$content.find('.mw-history-compareselectedversions-button').first().after(
' ',
$('<a>').attr({
class: 'unseendiff',
href: href
}).text('unseen')
);
});
(async () => {
let cspn = mw.config.get('wgCanonicalSpecialPageName');
let isBp = cspn === 'Blankpage';
if (!isBp && cspn !== 'Watchlist') return;
await mw.loader.using('mediawiki.util');
let notify = async (text, options, pn) => {
let msg = [document.createTextNode(text)];
if (pn) {
msg.push(
$('<p>').append(
$('<a>').attr('href', mw.util.getUrl(pn)).text(pn),
' ',
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'edit' }))
.text('edit')
),
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'history' }))
.text('history')
)
)
)[0]
);
}
if (isBp) {
await $.ready;
$('#mw-content-text').html(msg);
} else {
return mw.notify(msg, Object.assign(options || {}, {
tag: 'unseendiff'
}));
}
};
let getUrl = async pn => {
await mw.loader.using('mediawiki.api');
let page = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
if (!page.notificationtimestamp) {
notify(`Couldn't get the last seen time.`, {
type: 'warn'
}, pn);
return;
}
let rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (rev === page.lastrevid) {
notify('Already seen.', {
type: 'warn'
}, pn);
return;
}
if (!rev) {
rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
rvdir: 'newer',
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev) {
notify(`Couldn't get the last seen revision.`, {
type: 'warn'
}, pn);
return;
}
}
if (rev > page.lastrevid) {
notify(`Invalid rev for "${pn}" (rev: ${rev}, lastrevid: ${page.lastrevid})`, {
autoHideSeconds: 'long',
type: 'warn'
}, pn);
return;
}
return mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
};
if (isBp) {
let pn = mw.config.get('wgTitle').match(/^[^/]+\/unseendiff\/(.+)$/)?.[1];
if (!pn) return;
notify('Loading...', null, pn);
let href = await getUrl(pn);
if (!href) return;
notify('Redirecting...', null, pn);
location.href = href;
return;
}
let handler = async function (e) {
if (e.which > 2) return;
e.preventDefault();
let pn = this.dataset.pn;
if (!pn) {
notify(`Couldn't get the page name.`, {
type: 'error'
});
return;
}
let notifPromise = notify('Loading...', {
autoHideSeconds: 'long'
});
let href = await getUrl(pn);
if (!href) return;
$(`.unseendiff-loader[data-pn="${$.escapeSelector(pn)}"]`).attr({
class: 'unseendiff',
href: href,
target: '_blank'
}).off('click auxclick', handler);
if (e.type === 'auxclick' || e.ctrlKey || e.metaKey || e.shiftKey) {
open(href);
} else {
this.click();
}
(await notifPromise).close();
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-changeslist-src-mw-edit.mw-changeslist-watchedunseen:not(.mw-changeslist-watchedseen) .mw-changeslist-line-inner'
).each(function () {
let pn = this.dataset.targetPage ||
this.closest('[data-target-page]')?.dataset.targetPage ||
this.closest('table.mw-enhanced-rc')?.querySelector('[data-target-page]')?.dataset.targetPage;
if (!pn) return;
$('<span>').append(
$('<a>').attr({
class: 'unseendiff-loader',
href: mw.util.getUrl(`Special:BlankPage/unseendiff/${pn}`),
'data-pn': pn
}).on('click auxclick', handler).text('unseen')
).appendTo(
[...this.querySelectorAll('.mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
});
})();
['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
mw.loader.using('mediawiki.util', () => {
let watched = new Set();
let query = async lis => {
let titles = Object.keys(lis).slice(0, 50);
if (!titles.length) return;
await mw.loader.using('mediawiki.api');
let pages = (await new mw.Api().post({
action: 'query',
titles: titles,
prop: 'info',
inprop: 'notificationtimestamp|watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages;
for (let page of pages) {
if (!Object.hasOwn(lis, page.title)) continue;
if (page.watched) {
watched.add(page);
$(lis[page.title]).addClass('watched');
}
if (!page.notificationtimestamp) continue;
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev === page.lastrevid) continue;
if (rev > page.lastrevid) {
mw.notify($([
document.createTextNode('Invalid rev for "'),
$('<a>').attr({
href: mw.util.getUrl(page.title, { action: 'history' }),
target: '_blank'
}).text(page.title)[0],
document.createTextNode(`" (rev: ${rev}, lastrevid: ${page.lastrevid})`),
]), {
autoHideSeconds: 'long',
type: 'warn'
});
continue;
}
$('<span>').append(
$('<a>').attr({
class: 'unseendiff',
href: mw.util.getUrl(page.title, {
diff: page.lastrevid,
oldid: rev
})
}).text('unseen')
).appendTo(
lis[page.title].map(li => (
[...li.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(li).before(' ')
))
);
}
titles.forEach(title => {
delete lis[title];
});
query(lis);
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-contributions-list > li:not(.mw-contributions-current)[data-mw-revid]'
).each(function () {
let link = this.querySelector('a.mw-changeslist-date, a.mw-changeslist-history');
let pn = link ? new URLSearchParams(link.search).get('title') : '';
$('<span>').append(
$('<a>').attr({
class: 'mw-changeslist-diff',
href: mw.util.getUrl(pn, {
diff: 'cur',
oldid: this.dataset.mwRevid
})
}).text('cur')
).appendTo(
[...this.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
if (mw.config.get('wgWikiID') === 'wikidatawiki') return;
let lis = {};
$content.find('.mw-contributions-title').each(function () {
let title = this.textContent;
if (!Object.hasOwn(lis, title)) {
lis[title] = [];
}
lis[title].push(this.closest('li'));
});
Object.keys(lis).forEach(title => {
if (watched.has(title)) {
$(lis[title]).addClass('watched');
delete lis[title];
}
});
query(lis);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox9.js&action=raw&ctype=text/javascript');
mw.config.get('wgWikiID') === 'metawiki' &&
(async () => {
let css = mw.loader.addStyleTag(`.wishtitle {
font-size: 90%;
font-style: italic;
word-break: break-word;
}
.wishtitle > a {
color: var(--color-warning, #886425);
}
.wishtitle > a:visited {
color: var(--border-color-warning--hover, #735421);
}
.wishtitle-declined > a {
text-decoration: line-through;
}
.wishtitle-declined > a:hover,
.wishtitle-declined > a:focus,
.mw-underline-always .wishtitle-declined > a {
text-decoration: line-through underline;
}
#watchlist-edit-form .wishtitle {
display: inline-block;
}
.mw-search-result-heading > .wishtitle,
.catchangesviewer-table .wishtitle {
display: block;
}
.catchangesviewer-table:has(.wishtitle) {
white-space: wrap;
}`);
let lang = mw.config.get('wgUserLanguage');
let titles;
let loadTitles = async () => {
await mw.loader.using('mediawiki.storage');
titles = titles || mw.storage.getObject('wishtitles');
if (titles?.lang !== lang) {
titles = { lang, w: [], fa: [] };
}
};
let updateTitles = async (crwstatuses, crwcontinue) => {
await mw.loader.using('mediawiki.api');
let params = {
action: 'query',
list: 'communityrequests-wishes',
crwlang: lang,
crwstatuses: crwstatuses,
crwprop: 'title|updated',
crwsort: 'updated',
crwdir: 'ascending',
crwlimit: 'max',
crwcontinue: crwcontinue,
formatversion: 2
};
if (!crwcontinue && !crwstatuses && titles._) {
params.crwcontinue = `|${titles._}|0`;
}
let response = await new mw.Api().get(params);
let wishes = response?.query?.['communityrequests-wishes'];
if (wishes?.length) {
let $span = $('<span>');
wishes.forEach(w => {
let id = w.crwtitle.match(/^Community Wishlist\/W(\d+)/)?.[1];
if (!id) return;
titles.w[id - 1] = $span.html(w.title).text();
if (crwstatuses === 'declined') {
(titles.wd = titles.wd || []).push(id - 1);
}
let faId = w.crfatitle?.match(/^Community Wishlist\/FA(\d+)/)?.[1];
if (!faId) return;
titles.fa[faId - 1] = w.focusareatitle;
});
if (!crwstatuses) {
titles._ = wishes.at(-1).updated.replace(/\D/g, '');
}
}
let expiry = 86400;
if (crwstatuses || crwcontinue) {
let prev = mw.storage.getObject('_EXPIRY_wishtitles');
if (prev) {
expiry = Math.round(Date.now() / 1000) + 86400 - prev;
}
}
mw.storage.setObject('wishtitles', titles, expiry);
crwcontinue = response?.continue?.crwcontinue;
if (crwcontinue) {
await updateTitles(crwstatuses, crwcontinue);
}
};
let getTitle = id => (
id[0] === 'W' ? titles.w[id.slice(1) - 1] : titles.fa[id.slice(2) - 1]
);
let renderTitle = (title, id, tag = 'span') => {
let classes = 'wishtitle';
if (id[0] === 'W' && titles.wd?.includes(id.slice(1) - 1)) {
classes += ' wishtitle-declined';
}
return $(`<${tag}>`).addClass(classes).append(
$('<a>').attr({
href: `/wiki/Community_Wishlist/${id}`,
title: `Community Wishlist/${id}`
}).text(title)
);
};
let callback = ([id, links]) => {
let title = getTitle(id);
if (!title) {
return true;
}
$(links).after(' ', renderTitle(title, id));
};
let selector = '.mw-changeslist-title, ' +
'.mw-changeslist-log-entry > a:not(.mw-userlink), ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize :is(.mw-changeslist-line-inner, .mw-changeslist-line-inner-comment, .mw-enhanced-rc-nested) > .comment > a, ' +
'#watchlist-edit-form .cdx-table td > label > a, ' +
'.mw-search-result-heading > a:not(:has(> .ext-communityrequests-entity-link--label)), ' +
'.mw-contributions-title, ' +
'#mw-whatlinkshere-list li > bdi > a, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-logevent-loglines > li > a, ' +
'#mw-pages li > a, ' +
'.catchangesviewer-table td:nth-child(3) > a';
mw.hook('wikipage.content').add(async $content => {
let links = {};
$content.find('a').each(function () {
if (!this.matches(selector)) return;
let id = this.textContent.match(
/^(?:Talk:|Translations:)?Community Wishlist\/((?:W|FA)\d+)/
)?.[1];
if (!id) return;
(links[id] = links[id] || []).push(this);
});
links = Object.entries(links);
if (!links.length) return;
await loadTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles('declined');
links.forEach(callback);
});
let pn = mw.config.get('wgRelevantPageName');
let id = pn.match(/^(?:Talk:|Translations:)?Community_Wishlist\/((?:W|FA)\d+)/)?.[1];
if (!id) return;
await $.ready;
let extTitle = document.querySelector('.ext-communityrequests-wish--title');
if (extTitle && $('.mw-pt-languages-selected').attr('lang') === lang) return;
await loadTitles();
let title = getTitle(id);
if (!title) {
await updateTitles();
title = getTitle(id);
if (!title) {
await updateTitles('declined');
title = getTitle(id);
if (!title) return;
}
}
let $title = renderTitle(title, id, 'div');
if (mw.config.get('skin') === 'vector-2022') {
$title.prependTo('.vector-page-toolbar');
} else {
$title.insertAfter('#firstHeading');
}
css.textContent += ' .ext-communityrequests-entity-talk-header{display:none}';
if (extTitle) return;
document.title = document.title.replace(
pn.replaceAll('_', ' '),
`${pn.replace(`Community_Wishlist/${id}`, title)} ($&)`
);
})();
mw.config.get('wgWikiID') === 'metawiki' &&
mw.hook('wikipage.watchlistChange').add(async (isWatched, expiry) => {
if (![0, 1].includes(mw.config.get('wgNamespaceNumber'))) return;
let title = mw.config.get('wgTitle');
if (!/^Community Wishlist\/(?:W|FA)\d+$/.test(title)) return;
if (isWatched) {
await new mw.Api().watch(title + '/Votes', expiry);
mw.notify('Watching /Votes too.');
} else {
await new mw.Api().unwatch(title + '/Votes');
mw.notify('Unwatched /Votes too.');
}
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
$(async () => {
let $input = $('#wpTemplateSandboxTemplate');
if (!$input.length) return;
mw.loader.addStyleTag('#templatesandbox-editform .oo-ui-fieldLayout{max-width:50em} #templatesandbox-editform .oo-ui-fieldLayout-field{flex-grow:999}');
let makeTemplateField = () => new OO.ui.FieldLayout(
new mw.widgets.TitleInputWidget({
inputId: 'wpTemplateSandboxTemplate',
name: 'wpTemplateSandboxTemplate',
showMissing: false,
value: $input.val()
}),
{ label: 'Template name:' }
);
if (mw.loader.getState('ext.TemplateSandbox') !== 'registered') {
await mw.loader.using('mediawiki.widgets');
$input.parent().replaceWith(makeTemplateField().$element);
return;
}
let require = await mw.loader.using([
'ext.TemplateSandbox.TemplateSandboxTitleWidget',
'ext.TemplateSandbox.styles', 'jquery.makeCollapsible', 'user.options'
]);
let widget = new (require('ext.TemplateSandbox.TemplateSandboxTitleWidget'))({
$overlay: true,
id: 'wpTemplateSandboxPage',
maxLength: 255,
name: 'wpTemplateSandboxPage',
placeholder: 'Page title',
required: false,
tabIndex: 10,
templateTitleFunc: () => $('#wpTemplateSandboxTemplate').val()
});
widget.$element.attr('data-ooui', '{"_":"mw.widgets.TemplateSandboxTitleWidget"}')
.data('oouiInfused', widget);
let fieldset = new OO.ui.FieldsetLayout({
classes: ['mw-templatesandbox-fieldset', 'mw-collapsed'],
id: 'templatesandbox-editform',
items: [
makeTemplateField(),
new OO.ui.ActionFieldLayout(
widget,
new OO.ui.ButtonInputWidget({
id: 'wpTemplateSandboxPreview',
name: 'wpTemplateSandboxPreview',
label: 'Show preview',
tabIndex: 10,
type: 'submit',
useInputTag: true
}),
{ align: 'top' }
)
],
label: 'Preview page with this template'
});
fieldset.$label.append(' ', $('<span>').addClass('mw-collapsible-toggle-placeholder'));
fieldset.$group.addClass('mw-collapsible-content');
$('#templatesandbox-editform').replaceWith(fieldset.$element.makeCollapsible());
let modules = ['ext.TemplateSandbox'];
if (Number(mw.user.options.get('uselivepreview'))) {
modules.push('ext.TemplateSandbox.preview');
}
mw.loader.load(modules);
});
mw.config.get('wgWikiID') === 'enwiki' &&
mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist' &&
(async () => {
mw.loader.addStyleTag('.xfdnotifier-sublinks::before{content:" ["} .xfdnotifier-sublinks::after{content:"]"} .xfdnotifier-sublinks > span:not(:first-child)::before{content:"\\2009·\\2009"} .mw-portlet.vector-menu[id^="p-xfdnotifier-"] a{display:inline}');
await mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.storage']);
let xfds = [
{
id: 'rm',
label: 'RM',
full: 'Requested moves',
cat: 'Requested moves',
},
{
id: 'rmt',
label: 'RM/T',
full: 'Requested moves (technical)',
page: 'Wikipedia:Requested_moves/Technical_requests',
titleExtractor: $page => (
$page.find(`[data-mw*='"wt":"RMassist/core"']`).closest('li').map(function () {
return this.querySelector('a[rel="mw:WikiLink"]')?.title;
}).get()
)
},
{
id: 'afd',
label: 'AfD',
full: 'Articles for deletion',
cat: 'Articles for deletion'
},
{
id: 'mfd',
label: 'MfD',
full: 'Miscellaneous for deletion',
cat: 'Miscellaneous pages for deletion'
},
{
id: 'tfd',
label: 'TfD',
full: 'Templates for deletion',
cat: 'Templates for deletion'
},
{
id: 'tfm',
label: 'TfM',
full: 'Templates for merging',
cat: 'Templates for merging'
},
{
id: 'cfd',
label: 'CfD',
full: 'Categories for deletion',
cat: 'Categories for deletion'
},
{
id: 'cfr',
label: 'CfR',
full: 'Categories for renaming',
cat: 'Categories for renaming'
},
{
id: 'cfsr',
label: 'CfSR',
full: 'Categories for speedy renaming',
cat: 'Categories for speedy renaming'
},
{
id: 'cfm',
label: 'CfM',
full: 'Categories for merging',
cat: 'Categories for merging'
},
{
id: 'cfs',
label: 'CfS',
full: 'Categories for splitting',
cat: 'Categories for splitting'
},
{
id: 'cfl',
label: 'CfL',
full: 'Categories for listifying',
cat: 'Categories for listifying'
},
{
id: 'cfc',
label: 'CfC',
full: 'Categories for conversion',
cat: 'Categories for conversion'
},
{
id: 'cfgd',
label: 'CfGD',
full: 'Categories for general discussion',
cat: 'Categories for general discussion'
},
{
id: 'ffd',
label: 'FfD',
full: 'Files for discussion',
cat: 'Wikipedia files for discussion'
},
{
id: 'rfd',
label: 'RfD',
full: 'Redirects for discussion',
cat: 'All redirects for discussion'
},
{
id: 'prod',
label: 'PROD',
full: 'Articles proposed for deletion',
cat: 'All articles proposed for deletion'
}
];
window.xfd = xfds;
let queryTitles = async (xfd, titles) => {
if (!titles.length) return;
let response = await new mw.Api().get({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched) {
xfd.pages.push(p.title);
}
});
await queryTitles(xfd, titles.slice(50));
};
let queryPage = async xfd => {
let $page = $($.parseHTML(await $.get(
`https://en.wikipedia.org/w/rest.php/v1/page/${encodeURIComponent(xfd.page)}/html`
)));
await queryTitles(xfd, xfd.titleExtractor($page));
};
let queryCat = async (xfd, gcmcontinue) => {
let response = await new mw.Api().get({
action: 'query',
prop: 'info|categories',
inprop: 'watched',
clprop: 'sortkey',
clcategories: `Category:${xfd.cat}`,
generator: 'categorymembers',
gcmtitle: `Category:${xfd.cat}`,
gcmlimit: 'max',
gcmsort: 'timestamp',
gcmdir: 'older',
gcmcontinue: gcmcontinue,
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched && p.categories?.[0]?.sortkeyprefix !== ' ') {
xfd.pages.push(p.title);
}
});
if (response?.continue?.gcmcontinue) {
await queryCat(xfd, response.continue.gcmcontinue);
}
};
let show = async (xfd, lastId, isCache) => {
if (xfd.portlet && isCache) return;
let portletId = 'p-xfdnotifier-' + xfd.id;
if (xfd.portlet) {
$(xfd.portlet).find('ul').empty();
if (!xfd.pages.length) return;
} else {
await $.ready;
xfd.portlet = mw.util.addPortlet(portletId, xfd.label, '#' + lastId);
}
let $label = $(`#${portletId}-label`).attr('title', xfd.full);
if (xfd.page) {
$label.wrapInner($('<a>').attr('href', mw.util.getUrl(xfd.page)));
}
xfd.pages.forEach(p => {
let t = mw.Title.newFromText(p);
let isTalk = t.isTalkPage();
let $other = $('<a>').attr({
href: t[isTalk ? 'getSubjectPage' : 'getTalkPage']().getUrl(),
title: isTalk ? 'subject' : 'talk'
}).text(isTalk ? 's' : 't');
let link = mw.util.addPortletLink(portletId, t.getUrl(), p).querySelector('a');
$('<span>').addClass('xfdnotifier-sublinks').append(
$('<span>').append($other),
$('<span>').append(
$('<a>').attr({
href: t.getUrl({ action: 'history' }),
title: 'history'
}).text('h')
)
).insertAfter(link);
});
};
mw.hook('wikipage.content').add(mw.util.throttle(async () => {
let cache = mw.storage.getObject('xfdnotifier') || {};
let lastId = 'p-tb';
for (let xfd of xfds) {
let portletId = 'p-xfdnotifier-' + xfd.id;
let now = Math.floor(Date.now() / 1000);
if (now - cache[xfd.id]?.[0] < 600) {
xfd.pages = cache[xfd.id].slice(1);
await show(xfd, lastId, true);
lastId = portletId;
continue;
}
xfd.pages = [];
if (xfd.cat) {
await queryCat(xfd);
} else if (xfd.page) {
await queryPage(xfd);
}
cache[xfd.id] = [now, ...xfd.pages];
mw.storage.setObject('xfdnotifier', cache, 604800);
await show(xfd, lastId);
lastId = portletId;
}
}, 1800000));
})();
kd1zggs165g95b4odhhvkej1vxw7g95
735818
735817
2026-04-01T11:23:15Z
Nardog
40946
735818
javascript
text/javascript
(async function listTools() {
let pageAction = mw.config.get('wgAction');
let isView = pageAction === 'view';
let isEdit = ['edit', 'submit'].includes(pageAction);
if (!isView && !isEdit) return;
let pageType = mw.config.get('wgCanonicalSpecialPageName') ||
mw.config.get('wgNamespaceNumber');
if (isView && !pageType && !mw.config.exists('wgRedirectedFrom') &&
!mw.config.get('wgIsRedirect') &&
!mw.config.get('wgPageName').includes('/')
) {
return;
}
await mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api',
'mediawiki.interface.helpers.styles'
]);
mw.loader.addStyleTag(`.listtools:not(#mw-content-subtitle .listtools) {
font-size: 85%;
}
.listtools, .listtools a {
font-weight: normal !important;
font-style: normal;
}
.mw-datatable .listtools {
display: block;
}
.listtools + .mw-whatlinkshere-tools,
#watchlist-edit-form .listtools ~ .mw-changeslist-links,
.mw-special-DisambiguationPageLinks .listtools + a {
display: none;
}`);
let messages = Object.assign({
watched: 'Added "$1" to your watchlist',
watchFail: `Couldn't watch "$1"`,
unwatchFail: `Couldn't unwatch "$1"`
}, window.listtoolsMessages);
let getMsg = (key, ...args) => (
Object.hasOwn(messages, key) ? mw.format(messages[key], ...args) : key
);
let notif;
let watchHandler = async function (e) {
e.preventDefault();
let $link = $(this);
let $wrapper = $link.parent();
$link.detach();
let params = new URLSearchParams(this.search);
let action = params.get('action');
$wrapper.text(getMsg(action + 'ing'));
let pn = params.get('title').replaceAll('_', ' ');
let promise = new mw.Api()[action](pn);
if (notif) {
notif.close();
notif = null;
}
try {
let result = await promise;
if (!result || !result[action + 'ed']) throw '';
let newAction = action === 'watch' ? 'unwatch' : 'watch';
params.set('action', newAction);
$link.add(`.listtools-watch > a[href="${this.pathname + this.search}"]`)
.attr('href', this.pathname + '?' + params)
.text(getMsg(newAction));
if (action !== 'watch') return;
let require = await mw.loader.using([
'mediawiki.notification', 'mediawiki.watchstar.widgets'
]);
notif = await mw.notify(
new (require('mediawiki.watchstar.widgets'))('watch', pn, null, $.noop, {
message: getMsg('watched', pn)
}).$element,
{ tag: 'listtools' }
);
} catch {
notif = await mw.notify(getMsg(action + 'Fail', pn), {
tag: 'listtools',
type: 'error'
});
} finally {
$wrapper.html($link);
}
};
let extGetMain = function () {
return this.title;
};
let re = new RegExp(`(?:\\?title=|${
mw.util.escapeRegExp(mw.format(mw.config.get('wgArticlePath'), ''))
})([^#&?]+)`);
let processed = new WeakSet();
let processLinks = ($links, module, titles) => {
let isBatch = !!titles;
titles = titles || new Set();
$links.each(function (i) {
if (processed.has(this)) return;
let $link = $links.eq(i);
let pn;
if (module.useText) {
pn = $link.text();
} else {
let match = $link.attr('href')?.match(re);
if (!match) return;
pn = decodeURIComponent(match[1]);
}
let t = mw.Title.newFromText(pn);
if (!t) return;
if (module.titlesOnly) {
let text = $link.text();
if (text !== pn.replaceAll('_', ' ') &&
(text !== t.getMainText() || t.namespace === 2)
) {
return;
}
}
if ($link.is('.external, .extiw')) {
Object.assign(t, {
getMain: extGetMain,
host: this.host,
namespace: 0,
title: pn
});
} else {
if (t.namespace < 0) return;
if ($link.hasClass('new')) {
t.missing = true;
}
titles.add(t.getSubjectPage().toText());
}
let $tools = $('<span>').addClass('listtools mw-changeslist-links')
.data('listtools', t);
tools.forEach(tool => {
addTool($tools, tool);
});
if ($link.is(':is(del, bdi) > :only-child')) {
if (module.position === 'end') {
$link.parent().parent().append(' ', $tools);
} else {
$link.parent().after(' ', $tools);
}
} else if (module.position === 'end') {
$link.parent().append(' ', $tools);
} else {
$link.after(' ', $tools);
}
if (module.post) {
module.post($tools);
}
processed.add(this);
});
if (!isBatch) {
getWatched(titles);
}
};
let tools = [
{
name: 'edit',
url: t => t.getUrl({ action: 'edit' })
},
{
name: 'hist',
url: t => !t.missing && t.getUrl({ action: 'history' })
},
{
name: 'links',
url: t => mw.util.getUrl('Special:WhatLinksHere/' + t)
},
{
name: 'watch',
url: t => !t.host && t.getSubjectPage().getUrl({ action: 'watch' }),
callback: watchHandler
}
];
let addTool = ($tools, tool, escapedName) => {
let t = $tools.data('listtools');
let $duplicate = escapedName &&
$tools.children('.listtools-' + escapedName);
let url = tool.url;
if (typeof url === 'function') {
url = url(t);
if (!url) {
$duplicate?.remove();
return;
}
}
let $link = $('<a>').attr('href', url).text(getMsg(tool.name));
if (t.host) {
$link.prop('host', t.host);
}
if (tool.callback) {
$link.on('click', tool.callback);
}
let $wrapper = $('<span>').addClass('listtools-' + tool.name)
.append($link);
let $next = tool.next && $tools.children('.listtools-' + tool.next);
if ($next?.length) {
$duplicate?.remove();
$next.before($wrapper);
} else if ($duplicate?.length) {
$duplicate.replaceWith($wrapper);
} else {
$tools.append($wrapper);
}
};
let extend = tool => {
if (tool.label && !Object.hasOwn(messages, tool.label)) {
messages[tool.name] = tool.label;
}
if (tool.next) {
tool.next = $.escapeSelector(tool.next);
}
let existingTool = tools.find(t => t.name === tool.name);
if (existingTool) {
Object.assign(existingTool, tool);
} else {
tools.push(tool);
}
let escapedName = existingTool && $.escapeSelector(tool.name);
let $allTools = $('.listtools');
$allTools.each(function (i) {
addTool($allTools.eq(i), tool, escapedName);
});
};
let getWatched = async titles => {
if (!Array.isArray(titles)) {
titles = [...titles].slice(0, 500);
}
if (!titles.length) return;
(await new mw.Api().post({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages.forEach(page => {
if (!page.watched) return;
$(`.listtools-watch > a[href="${mw.util.getUrl(page.title, { action: 'watch' })}"]`)
.attr('href', mw.util.getUrl(page.title, { action: 'unwatch' }))
.text(getMsg('unwatch'));
});
getWatched(titles.slice(50));
};
mw.hook('listtools.ready').fire(extend);
let catTreeCallback = (records, observer) => {
let $links = $(records[0].target).find('.CategoryTreeItem > bdi > a');
if ($links.length) {
observer.takeRecords();
observer.disconnect();
processLinks($links, catTreeModule);
}
};
let catTreeModule = {
selector: '.CategoryTreeItem > bdi > a',
types: [14, 'CategoryTree'],
position: 'end',
post: $tools => {
$tools.parent().next('.CategoryTreeChildren').each(function () {
new MutationObserver(catTreeCallback)
.observe(this, { childList: true });
});
}
};
let modules = [
{
selector: '#mw-pages li > a, #mw-pages li > span > a',
types: [14]
},
catTreeModule,
{
selector: '#mw-imagepage-section-linkstoimage a, #mw-imagepage-section-globalusage a',
types: [6]
},
{
selector: '#mw-globalusage-result a',
types: ['GlobalUsage']
},
{
selector: '.mw-search-result-heading > a, .searchalttitle > a.mw-redirect, .iw-result__title > a, .mw-search-exists a',
types: ['Search']
},
{
selector: '.mw-search-createlink a',
types: ['Search'],
titlesOnly: true
},
{
selector: '#watchlist-edit-form .cdx-table td > label > a',
types: ['EditWatchlist']
},
{
selector: '.plainlinks > li > a',
types: ['AbuseLog'],
titlesOnly: true
},
{
selector: '#mw-allmessagestable td:first-child > a:first-child:not(.new)',
types: ['Allmessages'],
position: 'end'
},
{
selector: '.mw-spcontent li a',
types: ['DisambiguationPageLinks', 'Listredirects'],
titlesOnly: true
},
{
selector: 'li > a:first-child',
types: ['FileDuplicateSearch']
},
{
selector: '.TablePager_col_title > a:first-child, .TablePager_col_template > a',
types: ['LintErrors'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: 'form > ul > li > a',
types: ['Nuke'],
position: 'end',
titlesOnly: true
},
{
selector: '.page-assessments a',
types: ['PageAssessments'],
titlesOnly: true
},
{
selector: '.TablePager_col_pr_page > a',
types: ['Protectedpages'],
position: 'end'
},
{
selector: '#mw-content-text > ul a',
types: ['Protectedtitles'],
position: 'end'
},
{
selector: '.mw-fr-pending-changes-page-title',
types: ['PendingChanges'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: '#mw-content-text > ul a:first-child',
types: ['StablePages'],
position: 'end'
},
{
selector: '.TablePager_col__page a',
types: ['TopicSubscriptions']
},
{
selector: '.undeleteResult > a',
types: ['Undelete'],
position: 'end',
useText: true
},
{
selector: '.TablePager_col_img_name > a:first-child',
// types: ['Listfiles'],
position: 'end'
},
{
selector: '.mw-newpages-pagename',
post: $tools => {
let $contents = $tools.parent().contents();
$contents.slice(
$contents.index($tools) + 1,
$contents.index($contents.filter('.mw-newpages-length'))
).replaceWith(' ');
}
},
{
selector: '#mw-whatlinkshere-list li > bdi > a'
},
{
selector: '.mw-changeslist-log-entry > a:not(.mw-changeslist-log-gblblock a, .mw-changeslist-log-globalauth a)',
titlesOnly: true
},
{
selector: '.mw-logevent-loglines > li:not(.mw-logline-gblblock, .mw-logline-globalauth) > a',
types: ['Log'],
titlesOnly: true
},
{
selector: '#mw-diff-otitle1 > strong > a, #mw-diff-ntitle1 > strong > a',
types: ['ComparePages'],
position: 'end'
},
{
selector: '#movepage-oldlink, #movepage-newlink',
types: ['Movepage']
},
{
selector: '.mw-undelete-revision a:not(.mw-userlink, .mw-usertoollinks > a)',
types: ['Undelete'],
useText: true
},
{
selector: '.galleryfilename, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner-comment > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-enhanced-rc-nested > .comment > a'
},
{
selector: '.mw-spcontent li a',
position: 'end',
titlesOnly: true
}
];
if (isEdit) {
let post = $tools => {
if (!$tools[0].closest('.templatesUsed')) return;
$tools.parent().contents().last().each(function () {
this.textContent = this.textContent.slice(1);
}).end().slice(-3, -1).remove();
};
let callback = mw.util.debounce(() => {
processLinks(
$('.mw-editfooter-list a, #wikiPreview > .previewnote a'),
{ titlesOnly: true, post }
);
}, 500);
mw.hook('wikipage.editform').add($form => {
callback();
$form.find('.templatesUsed').each(function () {
if (processed.has(this)) return;
processed.add(this);
new MutationObserver(callback)
.observe(this, { childList: true, subtree: true });
});
});
} else if (typeof pageType === 'number') {
$(() => {
processLinks($('.subpages a, .mw-redirectedfrom a, .redirectText a'), {});
});
}
mw.hook('wikipage.content').add($content => {
let titles = new Set();
let $links = $content.find('a');
modules.forEach(module => {
if (module.types && !module.types.includes(pageType)) return;
processLinks($links.filter(module.selector), module, titles);
});
getWatched(titles);
});
}());
mw.hook('listtools.ready').add(extend => {
// extend({
// name: 'talk',
// url: t => !t.isTalkPage() && t.canHaveTalkPage() && t.getTalkPage().getUrl(),
// next: 'hist'
// });
extend({
name: 'subject',
url: t => t.isTalkPage() && t.getSubjectPage().getUrl(),
next: 'hist'
});
extend({
name: 'last',
url: t => !t.missing && t.getUrl({ diff: 'cur', diffonly: 1 }),
next: 'links'
});
// extend({
// name: 'purge',
// url: t => t.getUrl({ action: 'purge' }),
// next: 'watch',
// callback: function (e) {
// e.preventDefault();
// let $link = $(this);
// let $wrapper = $link.parent();
// $link.detach();
// $wrapper.text('purging');
// let pn = $wrapper.closest('.listtools').data('listtools').toText();
// new mw.Api().post({
// action: 'purge',
// forcelinkupdate: 1,
// titles: pn,
// formatversion: 2
// }).then(response => {
// if (response.purge[0].purged) {
// mw.notify(`Purged "${pn}"'`);
// }
// }).always(() => {
// $wrapper.html($link);
// });
// }
// });
extend({
name: 'copy',
url: '#',
callback: function (e) {
e.preventDefault();
let text = $(this).closest('.listtools').data('listtools').toText();
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch (err) {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
}
});
});
(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
mw.config.get('wgCanonicalSpecialPageName') !== 'GlobalContributions' &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector += ', ' + this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i + 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i + 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes += ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i + '/' + count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 + ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 + ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());
if (mw.config.get('wgNamespaceNumber') === 14 && (
mw.config.get('wgAction') === 'view' || !mw.config.get('wgArticleId')
)) {
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox8.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.DateFormatter',
'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget', 'mediawiki.widgets.datetime',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-movement',
'mediawiki.interface.helpers.styles', 'user.options'
]);
}
$(function moveHistory() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Move history', 't-movehistory').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.moveHistoryDialog) {
window.moveHistoryDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox5.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.Title', 'mediawiki.DateFormatter',
'oojs-ui-windows', 'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.DateInputWidget', 'oojs-ui.styles.icons-interactions',
'mediawiki.interface.helpers.styles'
]);
});
});
});
$(function sectionSearch() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Section search', 't-sectionsearch').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.sectionSearchDialog) {
window.sectionSearchDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox7.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-windows',
'mediawiki.widgets', 'mediawiki.widgets.NamespacesMultiselectWidget'
]);
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'CentralAuth' &&
mw.loader.using('jquery.tablesorter', function sortCentralAuthByEditCount() {
mw.hook('wikipage.content').add($content => {
let $table = $content.find('.mw-centralauth-wikislist').has('td');
if (!$table.length) return;
$table.tablesorter().data('tablesorter').sort([{ 4: 'desc' }, { 1: 'asc' }]);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
[10, 828].includes(mw.config.get('wgNamespaceNumber')) &&
!mw.config.get('wgTitle').endsWith('/doc') &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/AutoTestcases.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/TemplatePreviewGuard.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// $(function templatePreviewGuard() {
// let button = document.querySelector('input[name="wpTemplateSandboxPreview"]');
// if (!button) return;
// let proceed;
// button.addEventListener('click', e => {
// if (proceed) {
// proceed = false;
// return;
// }
// e.preventDefault();
// e.stopPropagation();
// let formData = new FormData(button.form);
// let page = formData.get('wpTemplateSandboxPage');
// let temp = formData.get('wpTemplateSandboxTemplate');
// if (!page || !temp) return;
// mw.loader.using('mediawiki.api').then(() => (
// new mw.Api().get({
// action: 'query',
// titles: page,
// prop: 'templates',
// tltemplates: temp,
// formatversion: 2
// })
// )).always(response => {
// if (((((response || {}).query || {}).pages || [])[0] || {}).templates ||
// confirm(`"${page}" doesn't appear to transclude "${temp}". Continue?`)
// ) {
// proceed = true;
// button.click();
// }
// });
// }, true);
// if (!mw.config.get('wgArticleId')) return;
// let widgetEl = document.querySelector('#wpTemplateSandboxPage.oo-ui-widget');
// if (!widgetEl) return;
// let pn = mw.config.get('wgPageName').replace(/_/g, ' ');
// mw.loader.using(['mediawiki.api', 'oojs-ui-core']).then(() => (
// new mw.Api().get({
// action: 'query',
// titles: pn,
// prop: 'transcludedin',
// tiprop: 'title',
// tilimit: 'max',
// formatversion: 2
// })
// )).then(response => {
// if (!response.batchcomplete) return;
// let pages = response.query.pages[0].transcludedin
// .filter(o => o.title !== pn);
// if (!pages.length) return;
// let widget = OO.ui.infuse(widgetEl);
// if (pages.length === 1) {
// widget.setValue(pages[0].title);
// return;
// }
// widget.$element.replaceWith(
// new OO.ui.ComboBoxInputWidget({
// id: 'wpTemplateSandboxPage',
// maxlength: widget.$input.prop('maxLength'),
// name: widget.$input.prop('name'),
// options: pages
// .sort((a, b) => a.ns - b.ns || -(a.title < b.title))
// .map(o => ({ data: o.title })),
// placeholder: widget.$input.prop('placeholder'),
// tabIndex: widget.getTabIndex(),
// value: widget.getValue()
// }).on('enter', e => {
// e.preventDefault();
// button.click();
// }).$element
// );
// });
// });
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(async () => {
let form = document.getElementById('editform');
if (!form) return;
let formData = new FormData(form);
let section = formData.get('wpSection');
if (section === 'new') return;
let widget = document.getElementById('wpSummaryWidget');
if (!widget) return;
let isOld = formData.get('altBaseRevId') > 0 ||
(formData.get('baseRevId') || formData.get('parentRevId')) !== formData.get('editRevId');
await mw.loader.using([
'jquery.textSelection', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core',
'oojs-ui.styles.icons-editing-core'
]);
let $textarea = $('#wpTextbox1');
let input = OO.ui.infuse(widget);
let button = new OO.ui.ButtonWidget({
framed: false,
icon: 'undo',
classes: ['autosectionlink-button'],
invisibleLabel: true,
label: 'Restore previous section link'
}).toggle().on('click', () => {
let cache = button.getData();
input.setValue(input.getValue().replace(
/^(\/\*.*?\*\/)?\s*/,
cache[0] ? '/* ' + cache[0] + ' */ ' : ''
));
updatePreview(cache[0]);
cache.reverse();
}).on('toggle', () => {
input.$input.css('width', `calc(100% - ${button.$element.width()}px)`);
});
input.$input.after(button.$element);
let update = mw.util.debounce($diff => {
let lines = $textarea.textSelection('getContents').replace(/\s+$/, '').split('\n');
let firstLineNum;
if (isOld) {
let i, lastLineNum;
$diff.find('td:last-child').each(function () {
if (this.classList.contains('diff-lineno')) {
i = this.textContent.replace(/\D+/g, '') - 1;
} else if (this.classList.contains('diff-context')) {
i++;
} else if (this.classList.contains('diff-addedline')) {
i++;
if (!firstLineNum) {
firstLineNum = i;
}
lastLineNum = i;
} else if (this.classList.contains('diff-empty')) {
if (!firstLineNum) {
firstLineNum = i === 0 ? 1 : i;
}
lastLineNum = i;
}
});
lines.length = lastLineNum || 0;
} else {
let origLines = $textarea.prop('defaultValue').replace(/\s+$/, '').split('\n');
firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
if (!firstLineNum) {
firstLineNum = lines.length < origLines.length
? lines.length
: 1;
}
for (let i = 1, x = lines.length, y = origLines.length;
(section ? i < x : i <= x) && lines[x - i] === origLines[y - i];
i++
) {
lines.pop();
}
}
let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 7;
lines.slice(firstLineNum).forEach(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
lowest = match[1].length;
}
});
let head;
lines.slice(0, firstLineNum).reverse().some(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
head = match[2];
return true;
}
});
head = head ? head
.replace(/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
.replace(/''(.+?)''/g, '$1')
.trim() : null;
let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
let prev = match[1];
if (section < 1 && lowest === 7 && !head) {
head = '';
}
if (prev === head) return;
input.setValue((typeof head === 'string' ? '/* ' + head + ' */ ' : '') + match[2]);
button.setData([prev, head]).toggle(true);
updatePreview(head);
}, 500);
let updatePreview = head => {
let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
if (!$preview.length) return;
let hasHead = typeof head === 'string';
let url = hasHead && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
let text = hasHead && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + (head || mw.messages.get('autocomment-top', '(top)'));
let $ac = $preview.children('.autocomment:first-child');
if ($ac.length && !$ac[0].previousSibling) {
if (hasHead) {
$ac.children('a').attr('href', url).text(text);
} else {
let node = $ac[0].nextSibling;
if (node?.nodeType === 3) {
node.textContent = node.textContent.replace(/^\s+/, '');
}
$ac.remove();
}
} else if (hasHead) {
$('<span>').addClass('autocomment').append(
$('<a>').attr({
href: url,
title: mw.config.get('wgPageName').replace(/_/g, ' ')
}).text(text),
mw.messages.get('colon-separator', ': ')
).prependTo($preview);
}
};
if (isOld) {
mw.hook('wikipage.diff').add(update);
} else {
$textarea.on('input', update);
mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
if (on && $codeMirror[0].CodeMirror) {
$codeMirror[0].CodeMirror.on('change', update);
}
});
mw.hook('ext.CodeMirror.input').add(update);
update();
}
new mw.Api().loadMessagesIfMissing(['autocomment-top', 'colon-separator']);
mw.loader.addStyleTag('.autosectionlink-button{position:absolute;top:0;right:0;margin:0}');
});
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(function copyRevId() {
let handler = function (e) {
e.preventDefault();
let text = this.closest('.diff td')?.querySelector('[data-mw-revid]')?.dataset.mwRevid ||
this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!text) return;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
document.execCommand('copy');
$input.remove();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id')
)
);
});
}());
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(() => {
let handler = async function (e) {
e.preventDefault();
let td = this.closest('.diff td');
let rev = td
? td.querySelector('[data-mw-revid]')?.dataset.mwRevid
: this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!rev) {
mw.notify(`Couldn't get the revision.`, {
tag: 'markasunseen',
type: 'error'
});
return;
}
let pn = td
? new URLSearchParams([...td.querySelectorAll('a')].pop()?.search).get('title')
: mw.config.get('wgPageName');
if (!pn) return;
await mw.loader.using('mediawiki.api');
let result = (await new mw.Api().postWithEditToken({
action: 'setnotificationtimestamp',
[td ? 'newerthanrevid' : 'torevid']: rev,
titles: pn,
formatversion: 2
})).setnotificationtimestamp?.[0];
if (Object.hasOwn(result, 'notificationtimestamp')) {
mw.notify(`Marked revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'success'
});
} else if (result?.notwatched) {
mw.notify('This page is not on your watchlist.', {
tag: 'markasunseen',
type: 'warn'
});
} else {
mw.notify(`Couldn't mark revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'error'
});
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions after this one as unseen'
}).on('click', handler).text('unseen'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions since this one as unseen'
}).on('click', handler).text('unseen')
)
);
});
})();
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
((mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4) ||
(mw.config.get('wgWikiID') === 'metawiki' && mw.config.get('wgPageContentModel') === 'wikitext')) &&
mw.loader.using(['mediawiki.util', 'mediawiki.Title'], function copyUnsig() {
let handler = function (e) {
e.preventDefault();
let parent = this.closest('li, td');
let ts = parent.textContent.match(/\d\d:\d\d, \d\d? [A-Z][a-z]+ \d{4}/)?.[0];
if (!ts) return;
let user = parent.querySelector('.mw-userlink').textContent;
if (mw.util.isIPv6Address(user)) {
user = user.toUpperCase();
}
let temp = mw.util.isIPAddress(user) ? 'unsigned IP' : 'unsigned';
let text = `{{subst:${temp}|${user}|${ts}}}`;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').filter(function () {
if (mw.config.get('wgWikiID') === 'metawiki') {
return true;
}
let link = this.querySelector('strong > a') ||
this.parentElement.querySelector('#differences-prevlink, #differences-nextlink');
if (!link) return;
let t = mw.Title.newFromText(mw.util.getParamValue('title', link.search));
return t.isTalkPage() || t.namespace === 4;
}).append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig')
)
);
});
});
// mw.config.get('wgAction') === 'history' &&
// mw.loader.using('mediawiki.util', function () {
// mw.hook('wikipage.content').add($content => {
// $content.find('a.mw-changeslist-date').after(function () {
// return [
// ' (',
// $('<a>').attr('href', mw.util.getUrl(null, {
// action: 'edit',
// oldid: this.closest('li').dataset.mwRevid
// })).text('e'),
// ')'
// ];
// });
// });
// });
// ['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
// mw.hook('wikipage.content').add($content => {
// $content.find('.mw-changeslist-history').parent().after(function () {
// return $('<span>').append(
// $('<a>').attr(
// 'href',
// this.firstElementChild.getAttribute('href').slice(0, -7) + 'edit'
// ).text('e')
// );
// });
// });
if (screen.width < 500) {
mw.loader.addStyleTag('@font-face{font-family:CharisW;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/017b2b2ad86e09d3c22b8cf0dfc78247/CharisSILRegular.ttf) format(truetype)} @font-face{font-family:CharisW;font-weight:700;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/6f5069ac6a300dad45383c952e92c573/CharisSILBold.ttf) format(truetype)} body .IPA{font-family:CharisW,sans-serif} .mw-highlight-lines > pre{width:120em}');
location.hash && $(() => {
let target = document.querySelector(':target');
if (target?.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
});
}
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
(mw.config.exists('wgCodeEditorCurrentLanguage') ||
mw.config.exists('cmMode') && mw.config.get('cmMode') !== 'mediawiki') &&
(function saveNEdit() {
let notif;
$(document.body).on('click', '#wpSave', async function (e) {
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey ||
e.originalEvent?.defaultPrevented
) {
return;
}
e.preventDefault();
await mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'jquery.textSelection', 'oojs-ui-core'
]);
let button = OO.ui.infuse(this.parentElement).setDisabled(true);
let $textarea = $('#wpTextbox1');
let text = $textarea.textSelection('getContents');
let $summary = $('#wpSummary');
let formData = new FormData(this.form);
let promise = new mw.Api().postWithEditToken({
action: 'edit',
title: mw.config.get('wgPageName'),
text: text,
section: formData.get('wpSection') || undefined,
summary: $summary.textSelection('getContents'),
[$('#wpMinoredit').prop('checked') ? 'minor' : 'notminor']: 1,
baserevid: formData.get('editRevId'),
basetimestamp: formData.get('wpEdittime'),
starttimestamp: formData.get('wpStarttime'),
watchlist: $('#wpWatchthis').prop('checked') ? 'watch' : 'unwatch',
watchlistexpiry: formData.get('wpWatchlistExpiry') || undefined,
undo: formData.get('wpUndidRevision') || undefined,
undoafter: formData.get('wpUndoAfter') || undefined,
contentformat: formData.get('format'),
contentmodel: formData.get('model'),
assertuser: mw.config.get('wgUserName'),
formatversion: 2
});
notif?.close();
notif = null;
try {
let response = await promise;
if (response?.edit?.result !== 'Success') throw '';
$('#editform > input[name="wpUndidRevision"], #editform > input[name="wpUndoAfter"]').remove();
$textarea.data('origtext', text).prop('defaultValue', text);
$summary.val($summary.prop('defaultValue'));
if (mw.loader.getState('mediawiki.editRecovery.edit') === 'ready') {
let storage = mw.loader.moduleRegistry['mediawiki.editRecovery.edit'].packageExports['storage.js'];
storage.deleteData(mw.config.get('wgPageName'));
storage.closeDatabase();
}
notif = await mw.notify(response.edit.nochange ? 'No change' : [
document.createTextNode('Saved'),
$('<p>').append(
new OO.ui.ButtonWidget({
href: mw.util.getUrl(),
target: '_blank',
label: 'View'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, {
diff: response.edit.newrevid || 'cur',
diffonly: 1
}),
target: '_blank',
label: 'Diff'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, { action: 'history' }),
target: '_blank',
label: 'History'
}).$element
)[0]
], { tag: 'savenedit' });
} catch (error) {
notif = await mw.notify(error?.error?.info || error || 'Save failed', {
autoHideSeconds: 'long',
tag: 'savenedit',
type: 'error'
});
} finally {
button.setDisabled();
}
});
}());
mw.config.get('wgNamespaceNumber') === 0 &&
mw.config.get('wgAction') === 'view' &&
mw.config.get('wgCategories')?.some(c => c.endsWith(' actors') || c.endsWith(' actresses')) &&
$(() => {
let n = $.escapeSelector(mw.config.get('wgTitle').replace(/ \(.+\)$/, ''));
let $links = $(`.hatnote a[title$="${n} filmography"], .hatnote a[title*="${n} on "], .hatnote a[title*="${n} performances"]`);
if (!$links.length) return;
let titles = {};
$links = $links.filter(function () {
let text = this.textContent;
return !(titles[text] = Object.hasOwn(titles, text));
});
mw.notify(
$links.length === 1
? $links.clone()
: $('<ul>').append($links.clone().wrap('<li>').parent()),
{ autoHideSeconds: 'long' }
);
});
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
let os = mw.user.options.get('userjs-rcmuter');
let set = new Set(os && os.split('|'));
let save = () => {
let ns = [...set].join('|');
if (ns === mw.user.options.get('userjs-rcmuter')) return;
new mw.Api().saveOption('userjs-rcmuter', ns);
mw.user.options.set('userjs-rcmuter', ns);
$edit.attr('data-rcmuter', set.size);
};
mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
let $edit = $('<a>').attr({
class: 'rcmuter-edit',
href: '#',
'data-rcmuter': set.size
}).text('Edit muted').on('click', e => {
e.preventDefault();
mw.loader.using([
'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
let multiselect = new mw.widgets.UsersMultiselectWidget({
$overlay: dialog.$overlay,
ipAllowed: true,
selected: [...set]
}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
let instance = dialog.open({
message: $([
document.createTextNode('Muted users:'),
multiselect.$element[0]
]),
size: 'medium'
});
instance.opened.then(() => {
setTimeout(() => {
multiselect.focus().menu.toggle(false);
});
});
instance.closed.then(result => {
if (!result || result.action !== 'accept') return;
set = new Set(multiselect.getSelectedUsernames());
save();
mw.notify('Changes will take effect in next load.', {
tag: 'rcmuter'
});
});
});
});
let buttonsShown;
let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
e.preventDefault();
if (buttonsShown) {
mw.hook('wikipage.content').remove(addButtons);
$('.rcmuter-toggle').remove();
this.textContent = 'Show toggle buttons';
} else {
mw.hook('wikipage.content').add(addButtons);
this.textContent = 'Hide toggle buttons';
}
buttonsShown = !buttonsShown;
});
let $toggle = $('<a>').attr({
class: 'rcmuter-togglemuted',
href: '#'
}).text('Show muted').on('click', function (e) {
e.preventDefault();
this.textContent = document.body.classList.toggle('rcmuter-disabled')
? 'Hide muted'
: 'Show muted';
});
let $toggleSpan = $('<span>').hide().append($toggle);
mw.util.addSubtitle(
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append($edit),
$('<span>').append($toggleButtons),
$toggleSpan
)[0]
);
let toggle = function (e) {
e.preventDefault();
let user = $(this)
.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
.last().text().trim();
if (!user) {
mw.notify(`Can't retrieve the username.`, {
tag: 'rcmuter',
type: 'error'
});
return;
}
let muting = this.parentElement.classList.toggle('rcmuter-unmute');
set[muting ? 'add' : 'delete'](user);
save();
this.textContent = muting ? 'unmute' : 'mute';
mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
tag: 'rcmuter'
});
};
let addButtons = $content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) {
$content = $('#mw-content-text');
if ($content.has('.rcmuter-toggle').length) return;
}
let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
let $muted = $tools.filter('.rcmuter-muted *');
$tools.not($muted).append(
$('<span>').addClass('rcmuter-toggle').append(
$('<a>').attr('href', '#').text('mute').on('click', toggle)
)
);
if (!$muted.length) return;
$muted.append(
$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
$('<a>').attr('href', '#').text('unmute').on('click', toggle)
)
);
};
let mutedCount;
let filter = function () {
let muted = set.has(this.textContent);
if (muted) mutedCount++;
return muted;
};
mw.hook('wikipage.content').add($content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) return;
if (!set.size) {
$toggleSpan.hide();
return;
}
mutedCount = 0;
$content.find('.changedby > .mw-userlink:only-child')
.filter(filter).closest('table').addClass('rcmuter-muted');
$content.find('.mw-userlink:not(.changedby > *, .comment *, .rcmuter-muted *)')
.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
$toggleSpan.toggle(!!mutedCount);
$toggle.attr('data-rcmuter', mutedCount);
});
});
location.hostname.endsWith('.wikipedia.org') &&
mw.config.get('wgNamespaceNumber') % 2 === 0 &&
// mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.util')).then(function refRenamer() {
if (!document.getElementById('p-tb')) return;
let messages = Object.assign({
portlet: 'RefRenamer',
loading: 'Loading RefRenamer...'
}, window.refrenamerMessages);
let clicked;
mw.util.addPortletLink('p-tb', '#', messages.portlet, 't-refrenamer').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.refRenamer) {
window.refRenamer();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox6.js&action=raw&ctype=text/javascript');
mw.notify(messages.loading, {
autoHideSeconds: 'long',
tag: 'refrenamer'
});
});
});
if (['edit', 'submit'].includes(mw.config.get('wgAction'))) {
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/ExpandContractions.js&action=raw&ctype=text/javascript', 's');
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/Unpipe.js&action=raw&ctype=text/javascript', 's');
}
mw.config.get('wgAction') !== 'history' &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/CopyCodeBlock.js&action=raw&ctype=text/javascript', 's');
mw.config.exists('wgDiffNewId') &&
mw.config.get('wgDiscussionToolsFeaturesEnabled') &&
(function () {
let data = {}, clickHandler, autoClear, run;
window.dtc = data;
let highlight = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
mw.loader.moduleRegistry['ext.discussionTools.init'].packageExports['highlighter.js']
.highlightNewComments(mw.dt.pageThreads, true, ids);
if (clickHandler) {
$(document.body).off('click', clickHandler);
return;
}
$._data(document.body, 'events').click.some(o => {
if (String(o.handler).includes('highlighter.clearHighlightTargetComment(')) {
$(document.body).off('click', o.handler);
clickHandler = o.handler;
return true;
}
});
$._data(window, 'events').popstate.some(o => {
if (String(o.handler).includes('highlighter.highlightTargetComment(')) {
$(window).off('popstate', o.handler);
return true;
}
});
};
let scroll = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
let yToSpan = Object.fromEntries(
ids.map(id => document.getElementById(id)).filter(Boolean)
.map(span => [span.getBoundingClientRect().y, span])
);
let ys = Object.keys(yToSpan);
if (!ys.length) return;
let lower = ys.filter(y => y > 10);
if (!lower.length ||
Math.max(...lower) < document.documentElement.clientHeight
) {
yToSpan[Math.min(...ys)].scrollIntoView();
} else {
yToSpan[Math.min(...lower)].scrollIntoView();
}
};
let scrollToNext = function (e) {
e.preventDefault();
let revId = mw.config.get('wgDiffOldId');
if (!revId || !data[revId]) return;
let i = data[revId].indexOf(
this.closest('[data-mw-thread-id]').dataset.mwThreadId
);
if (i === -1) return;
let next = data[revId][i + 1] || data[revId][0];
document.getElementById(next).scrollIntoView();
};
mw.hook('wikipage.content').add(async $content => {
let revId = mw.config.get('wgDiffOldId');
if (!revId) return;
let param = new URLSearchParams(location.search).get('diffonly');
if (param && param !== '0') return;
if (data[revId]) {
highlight(revId);
return;
}
await mw.loader.using(['ext.discussionTools.init', 'mediawiki.util']);
let begin = Date.parse($('#mw-diff-otitle1 .mw-diff-timestamp').data('timestamp'));
data[revId] = mw.dt.pageThreads.getCommentItems()
.filter(c => c.timestamp > begin).map(c => c.id);
if (!data[revId].length) return;
await new Promise(setTimeout);
highlight(revId);
$content.find('.ext-discussiontools-init-replylink-buttons').filter(function () {
return data[revId].includes(this.dataset.mwThreadId);
}).children('span:last-of-type').before(
' | ',
$('<a>').attr({
href: '#',
role: 'button'
}).text('next').on('click', scrollToNext)
);
if (run || !document.getElementById('p-tb')) return;
run = true;
let portlet = mw.util.addPortletLink('p-tb', '#', 'Scroll to next', 't-scrolltonext');
portlet.firstElementChild.addEventListener('click', e => {
e.preventDefault();
scroll(mw.config.get('wgDiffOldId'));
});
mw.util.addPortletLink('p-tb', '#', 'Toggle highlight', 't-togglehighlight').firstElementChild.addEventListener('click', e => {
e.preventDefault();
autoClear = !autoClear;
if (autoClear) {
$(document.body).on('click', clickHandler)[0].click();
} else {
highlight(mw.config.get('wgDiffOldId'));
}
});
mw.loader.addStyleTag(`#t-scrolltonext{position:fixed;bottom:${portlet.clientHeight}px} #t-togglehighlight{position:fixed;bottom:0}`);
});
}());
mw.config.get('wgNamespaceNumber') === 6 &&
mw.config.get('wgAction') === 'view' &&
mw.hook('wikipage.content').add($content => {
$content.find('.filehistory .mw-usertoollinks-contribs').after(function () {
return [
' | ',
$('<a>').attr('href', `${
mw.config.get('wgScript')
}?title=Special:ListFiles/${
this.pathname.replace(/^.+\//, '')
}&ilshowall=1`).text('uploads')
];
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function () {
if (!$('input[name="wpSection"]').val()) return;
mw.hook('wikipage.content').add(async $content => {
let $refs = $content.find('.mw-ext-cite-warning-sectionpreview_no_text');
if (!$refs.length) return;
let ids = {};
$refs.each(function () {
ids[this.closest('[id]').id.replace(/-\d+$/, '')] = this;
});
let response = await $.get(`/api/rest_v1/page/html/${encodeURIComponent(mw.config.get('wgPageName'))}`);
$($.parseHTML(response)).find('.mw-reference-text').each(function () {
ids[this.id.replace(/^mw-reference-text-|-\d+$/g, '')]?.replaceWith(this);
});
});
});
mw.hook('moremenu.ready').add(config => {
$('#mm-page-purge-cache > a').on('click', e => {
e.preventDefault();
new mw.Api().post({
action: 'purge',
forcelinkupdate: 1,
titles: config.page.name,
formatversion: 2
}).then(() => {
location.href = mw.util.getUrl();
});
});
$('#mm-page-search-search-history-wikiblame > a').on('click', function (e) {
e.preventDefault();
let q = prompt();
if (q === null) return;
let href = this.href;
if (q) {
let removal = q[0] === '!';
if (removal) {
q = q.slice(1);
}
href += '&needle=' + encodeURIComponent(q);
if (removal) {
href += '&binary_search_inverse=on';
}
href += '&force_wikitags=on';
}
open(href, '_blank');
});
$('#mm-page-expand-templates > a').on('click auxclick', function (e) {
if (e.which > 2) return;
e.preventDefault();
let revId = mw.config.get('wgRevisionId') || Number($('input[name=oldid]').val());
let url = revId
? '/w/rest.php/v1/revision/' + revId
: '/w/rest.php/v1/page/' + config.page.encodedName;
$.get(url).then(response => {
$('<form>').attr({
method: 'post',
action: this.href,
target: '_blank'
}).append(
[
['wpInput', response.source],
['wpContextTitle', config.page.name],
['wpRemoveComments', 1]
].map(([n, v]) => $('<input>').attr({
name: n,
type: 'hidden'
}).val(v))
).appendTo(document.body).trigger('submit').remove();
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'ApiSandbox' &&
mw.hook('apisandbox.formatRequest').add((...args) => {
args[4].complete = function () {
setTimeout(() => {
mw.hook('wikipage.content').fire($('.oo-ui-pageLayout-active'));
}, 100);
};
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.storage')).then(async () => {
let infuseAndCall = (query, method, ...args) => {
let $widget = $(query);
if ($widget.length) {
return OO.ui.infuse($widget)[method](...args);
}
};
let section = $('input[name="wpSection"]').val();
if (section) {
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let save = () => {
let newSource = $textarea.textSelection('getContents');
if (newSource === source) {
mw.storage.session.remove('editfullpage');
} else {
mw.storage.session.setObject('editfullpage', [
mw.config.get('wgPageName'),
section,
newSource.trimEnd(),
infuseAndCall('#wpSummaryWidget', 'getValue') || '',
Number(infuseAndCall('#wpMinoreditWidget', 'isSelected')) || 0,
Number(infuseAndCall('#wpWatchthisWidget', 'isSelected')) || 0,
infuseAndCall('#wpWatchlistExpiryWidget', 'getValue') || 'infinite'
]);
}
};
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
setInterval(() => {
mw.requestIdleCallback(save);
}, 3000);
window.addEventListener('beforeunload', save);
return;
}
let data = mw.storage.session.getObject('editfullpage');
mw.storage.session.remove('editfullpage');
console.log(data);
if (!data || data[0] !== mw.config.get('wgPageName')) return;
let isNew = data[1] === 'new';
let isLead = data[1] === '0';
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let newSource, start, msg, notifOpts = { autoHideSeconds: 'long' };
let orig = [];
if (isNew) {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
newSource = source + (data[3] ? '\n== ' + data[3] + ' ==\n\n' : '\n') + data[2] + '\n';
start = source.length;
} else {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core', 'mediawiki.api']);
let { parse } = await new mw.Api().get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
wrapoutputclass: '',
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
formatversion: 2
});
let target = !isLead && parse.sections.find(s => s.index === data[1]);
if (isLead || target) {
let next = parse.sections.find(s => s.index - 1 === Number(data[1]));
newSource = (isLead ? '' : [...source].slice(0, target.byteoffset)).join('') +
data[2] + (next ? '\n\n' + [...source].slice(next.byteoffset).join('') : '\n');
start = isLead ? 0 : target.byteoffset;
} else {
newSource = source + '\n\n' + data[2] + '\n';
start = source.length;
msg = `Section restored. Couldn't find the section. The source is appended at bottom.`;
notifOpts.type = 'warn';
}
orig[0] = infuseAndCall('#wpSummaryWidget', 'getValue');
infuseAndCall('#wpSummaryWidget', 'setValue', data[3]);
}
$textarea.textSelection('setContents', newSource);
orig[1] = infuseAndCall('#wpMinoreditWidget', 'getSelected');
infuseAndCall('#wpMinoreditWidget', 'setSelected', data[4]);
orig[2] = infuseAndCall('#wpWatchthisWidget', 'getSelected');
infuseAndCall('#wpWatchthisWidget', 'setSelected', data[5]);
orig[3] = infuseAndCall('#wpWatchlistExpiryWidget', 'getValue');
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', data[6]);
setTimeout(() => {
$textarea.textSelection('setSelection', { start });
});
let notif = await mw.notify($([
document.createTextNode(msg || 'Section restored.'),
$('<p>').append(
new OO.ui.ButtonWidget({
flags: 'destructive',
label: 'Discard'
}).on('click', () => {
$textarea.textSelection('setContents', source);
if (orig[0]) {
infuseAndCall('#wpSummaryWidget', 'setValue', orig[0]);
}
infuseAndCall('#wpMinoreditWidget', 'setSelected', orig[1]);
infuseAndCall('#wpWatchthisWidget', 'setSelected', orig[2]);
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', orig[3]);
notif.close();
}).$element
)[0]
]), notifOpts);
});
mw.config.exists('wgPostEdit') &&
mw.loader.using('mediawiki.storage', () => {
mw.storage.session.remove('editfullpage');
});
mw.config.get('wgAction') === 'history' &&
mw.hook('wikipage.content').add(async $content => {
if (!$content.has('.mw-history-line-updated').length) return;
let href = $content.find('a.mw-history-histlinks-current:not(.mw-history-line-updated a)').attr('href');
if (!href) {
await mw.loader.using(['mediawiki.api', 'mediawiki.util']);
let page = (await new mw.Api().get({
action: 'query',
titles: mw.config.get('wgPageName'),
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev >= page.lastrevid) return;
href = mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
}
$content.find('.mw-history-compareselectedversions-button').first().after(
' ',
$('<a>').attr({
class: 'unseendiff',
href: href
}).text('unseen')
);
});
(async () => {
let cspn = mw.config.get('wgCanonicalSpecialPageName');
let isBp = cspn === 'Blankpage';
if (!isBp && cspn !== 'Watchlist') return;
await mw.loader.using('mediawiki.util');
let notify = async (text, options, pn) => {
let msg = [document.createTextNode(text)];
if (pn) {
msg.push(
$('<p>').append(
$('<a>').attr('href', mw.util.getUrl(pn)).text(pn),
' ',
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'edit' }))
.text('edit')
),
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'history' }))
.text('history')
)
)
)[0]
);
}
if (isBp) {
await $.ready;
$('#mw-content-text').html(msg);
} else {
return mw.notify(msg, Object.assign(options || {}, {
tag: 'unseendiff'
}));
}
};
let getUrl = async pn => {
await mw.loader.using('mediawiki.api');
let page = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
if (!page.notificationtimestamp) {
notify(`Couldn't get the last seen time.`, {
type: 'warn'
}, pn);
return;
}
let rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (rev === page.lastrevid) {
notify('Already seen.', {
type: 'warn'
}, pn);
return;
}
if (!rev) {
rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
rvdir: 'newer',
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev) {
notify(`Couldn't get the last seen revision.`, {
type: 'warn'
}, pn);
return;
}
}
if (rev > page.lastrevid) {
notify(`Invalid rev for "${pn}" (rev: ${rev}, lastrevid: ${page.lastrevid})`, {
autoHideSeconds: 'long',
type: 'warn'
}, pn);
return;
}
return mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
};
if (isBp) {
let pn = mw.config.get('wgTitle').match(/^[^/]+\/unseendiff\/(.+)$/)?.[1];
if (!pn) return;
notify('Loading...', null, pn);
let href = await getUrl(pn);
if (!href) return;
notify('Redirecting...', null, pn);
location.href = href;
return;
}
let handler = async function (e) {
if (e.which > 2) return;
e.preventDefault();
let pn = this.dataset.pn;
if (!pn) {
notify(`Couldn't get the page name.`, {
type: 'error'
});
return;
}
let notifPromise = notify('Loading...', {
autoHideSeconds: 'long'
});
let href = await getUrl(pn);
if (!href) return;
$(`.unseendiff-loader[data-pn="${$.escapeSelector(pn)}"]`).attr({
class: 'unseendiff',
href: href,
target: '_blank'
}).off('click auxclick', handler);
if (e.type === 'auxclick' || e.ctrlKey || e.metaKey || e.shiftKey) {
open(href);
} else {
this.click();
}
(await notifPromise).close();
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-changeslist-src-mw-edit.mw-changeslist-watchedunseen:not(.mw-changeslist-watchedseen) .mw-changeslist-line-inner'
).each(function () {
let pn = this.dataset.targetPage ||
this.closest('[data-target-page]')?.dataset.targetPage ||
this.closest('table.mw-enhanced-rc')?.querySelector('[data-target-page]')?.dataset.targetPage;
if (!pn) return;
$('<span>').append(
$('<a>').attr({
class: 'unseendiff-loader',
href: mw.util.getUrl(`Special:BlankPage/unseendiff/${pn}`),
'data-pn': pn
}).on('click auxclick', handler).text('unseen')
).appendTo(
[...this.querySelectorAll('.mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
});
})();
['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
mw.loader.using('mediawiki.util', () => {
let watched = new Set();
let query = async lis => {
let titles = Object.keys(lis).slice(0, 50);
if (!titles.length) return;
await mw.loader.using('mediawiki.api');
let pages = (await new mw.Api().post({
action: 'query',
titles: titles,
prop: 'info',
inprop: 'notificationtimestamp|watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages;
for (let page of pages) {
if (!Object.hasOwn(lis, page.title)) continue;
if (page.watched) {
watched.add(page);
$(lis[page.title]).addClass('watched');
}
if (!page.notificationtimestamp) continue;
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev === page.lastrevid) continue;
if (rev > page.lastrevid) {
mw.notify($([
document.createTextNode('Invalid rev for "'),
$('<a>').attr({
href: mw.util.getUrl(page.title, { action: 'history' }),
target: '_blank'
}).text(page.title)[0],
document.createTextNode(`" (rev: ${rev}, lastrevid: ${page.lastrevid})`),
]), {
autoHideSeconds: 'long',
type: 'warn'
});
continue;
}
$('<span>').append(
$('<a>').attr({
class: 'unseendiff',
href: mw.util.getUrl(page.title, {
diff: page.lastrevid,
oldid: rev
})
}).text('unseen')
).appendTo(
lis[page.title].map(li => (
[...li.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(li).before(' ')
))
);
}
titles.forEach(title => {
delete lis[title];
});
query(lis);
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-contributions-list > li:not(.mw-contributions-current)[data-mw-revid]'
).each(function () {
let link = this.querySelector('a.mw-changeslist-date, a.mw-changeslist-history');
let pn = link ? new URLSearchParams(link.search).get('title') : '';
$('<span>').append(
$('<a>').attr({
class: 'mw-changeslist-diff',
href: mw.util.getUrl(pn, {
diff: 'cur',
oldid: this.dataset.mwRevid
})
}).text('cur')
).appendTo(
[...this.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
if (mw.config.get('wgWikiID') === 'wikidatawiki') return;
let lis = {};
$content.find('.mw-contributions-title').each(function () {
let title = this.textContent;
if (!Object.hasOwn(lis, title)) {
lis[title] = [];
}
lis[title].push(this.closest('li'));
});
Object.keys(lis).forEach(title => {
if (watched.has(title)) {
$(lis[title]).addClass('watched');
delete lis[title];
}
});
query(lis);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox9.js&action=raw&ctype=text/javascript');
mw.config.get('wgWikiID') === 'metawiki' &&
(async () => {
let css = mw.loader.addStyleTag(`.wishtitle {
font-size: 90%;
font-style: italic;
word-break: break-word;
}
.wishtitle > a {
color: var(--color-warning, #886425);
}
.wishtitle > a:visited {
color: var(--border-color-warning--hover, #735421);
}
.wishtitle-declined > a {
text-decoration: line-through;
}
.wishtitle-declined > a:hover,
.wishtitle-declined > a:focus,
.mw-underline-always .wishtitle-declined > a {
text-decoration: line-through underline;
}
#watchlist-edit-form .wishtitle {
display: inline-block;
}
.mw-search-result-heading > .wishtitle,
.catchangesviewer-table .wishtitle {
display: block;
}
.catchangesviewer-table:has(.wishtitle) {
white-space: wrap;
}`);
let lang = mw.config.get('wgUserLanguage');
let titles;
let loadTitles = async () => {
await mw.loader.using('mediawiki.storage');
titles = titles || mw.storage.getObject('wishtitles');
if (titles?.lang !== lang) {
titles = { lang, w: [], fa: [] };
}
};
let updateTitles = async (crwstatuses, crwcontinue) => {
await mw.loader.using('mediawiki.api');
let params = {
action: 'query',
list: 'communityrequests-wishes',
crwlang: lang,
crwstatuses: crwstatuses,
crwprop: 'title|updated',
crwsort: 'updated',
crwdir: 'ascending',
crwlimit: 'max',
crwcontinue: crwcontinue,
formatversion: 2
};
if (!crwcontinue && !crwstatuses && titles._) {
params.crwcontinue = `|${titles._}|0`;
}
let response = await new mw.Api().get(params);
let wishes = response?.query?.['communityrequests-wishes'];
if (wishes?.length) {
let $span = $('<span>');
wishes.forEach(w => {
let id = w.crwtitle.match(/^Community Wishlist\/W(\d+)/)?.[1];
if (!id) return;
titles.w[id - 1] = $span.html(w.title).text();
if (crwstatuses === 'declined') {
(titles.wd = titles.wd || []).push(id - 1);
}
let faId = w.crfatitle?.match(/^Community Wishlist\/FA(\d+)/)?.[1];
if (!faId) return;
titles.fa[faId - 1] = w.focusareatitle;
});
if (!crwstatuses) {
titles._ = wishes.at(-1).updated.replace(/\D/g, '');
}
}
let expiry = 86400;
if (crwstatuses || crwcontinue) {
let prev = mw.storage.getObject('_EXPIRY_wishtitles');
if (prev) {
expiry = Math.round(Date.now() / 1000) + 86400 - prev;
}
}
mw.storage.setObject('wishtitles', titles, expiry);
crwcontinue = response?.continue?.crwcontinue;
if (crwcontinue) {
await updateTitles(crwstatuses, crwcontinue);
}
};
let getTitle = id => (
id[0] === 'W' ? titles.w[id.slice(1) - 1] : titles.fa[id.slice(2) - 1]
);
let renderTitle = (title, id, tag = 'span') => {
let classes = 'wishtitle';
if (id[0] === 'W' && titles.wd?.includes(id.slice(1) - 1)) {
classes += ' wishtitle-declined';
}
return $(`<${tag}>`).addClass(classes).append(
$('<a>').attr({
href: `/wiki/Community_Wishlist/${id}`,
title: `Community Wishlist/${id}`
}).text(title)
);
};
let callback = ([id, links]) => {
let title = getTitle(id);
if (!title) {
return true;
}
$(links).after(' ', renderTitle(title, id));
};
let selector = '.mw-changeslist-title, ' +
'.mw-changeslist-log-entry > a:not(.mw-userlink), ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize :is(.mw-changeslist-line-inner, .mw-changeslist-line-inner-comment, .mw-enhanced-rc-nested) > .comment > a, ' +
'#watchlist-edit-form .cdx-table td > label > a, ' +
'.mw-search-result-heading > a:not(:has(> .ext-communityrequests-entity-link--label)), ' +
'.mw-contributions-title, ' +
'#mw-whatlinkshere-list li > bdi > a, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-logevent-loglines > li > a, ' +
'#mw-pages li > a, ' +
'.catchangesviewer-table td:nth-child(3) > a';
mw.hook('wikipage.content').add(async $content => {
let links = {};
$content.find('a').each(function () {
if (!this.matches(selector)) return;
let id = this.textContent.match(
/^(?:Talk:|Translations:)?Community Wishlist\/((?:W|FA)\d+)/
)?.[1];
if (!id) return;
(links[id] = links[id] || []).push(this);
});
links = Object.entries(links);
if (!links.length) return;
await loadTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles('declined');
links.forEach(callback);
});
let pn = mw.config.get('wgRelevantPageName');
let id = pn.match(/^(?:Talk:|Translations:)?Community_Wishlist\/((?:W|FA)\d+)/)?.[1];
if (!id) return;
await $.ready;
let extTitle = document.querySelector('.ext-communityrequests-wish--title');
if (extTitle && $('.mw-pt-languages-selected').attr('lang') === lang) return;
await loadTitles();
let title = getTitle(id);
if (!title) {
await updateTitles();
title = getTitle(id);
if (!title) {
await updateTitles('declined');
title = getTitle(id);
if (!title) return;
}
}
let $title = renderTitle(title, id, 'div');
if (mw.config.get('skin') === 'vector-2022') {
$title.prependTo('.vector-page-toolbar');
} else {
$title.insertAfter('#firstHeading');
}
css.textContent += ' .ext-communityrequests-entity-talk-header{display:none}';
if (extTitle) return;
document.title = document.title.replace(
pn.replaceAll('_', ' '),
`${pn.replace(`Community_Wishlist/${id}`, title)} ($&)`
);
})();
mw.config.get('wgWikiID') === 'metawiki' &&
mw.hook('wikipage.watchlistChange').add(async (isWatched, expiry) => {
if (![0, 1].includes(mw.config.get('wgNamespaceNumber'))) return;
let title = mw.config.get('wgTitle');
if (!/^Community Wishlist\/(?:W|FA)\d+$/.test(title)) return;
if (isWatched) {
await new mw.Api().watch(title + '/Votes', expiry);
mw.notify('Watching /Votes too.');
} else {
await new mw.Api().unwatch(title + '/Votes');
mw.notify('Unwatched /Votes too.');
}
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
$(async () => {
let $input = $('#wpTemplateSandboxTemplate');
if (!$input.length) return;
mw.loader.addStyleTag('#templatesandbox-editform .oo-ui-fieldLayout{max-width:50em} #templatesandbox-editform .oo-ui-fieldLayout-field{flex-grow:999}');
let makeTemplateField = () => new OO.ui.FieldLayout(
new mw.widgets.TitleInputWidget({
inputId: 'wpTemplateSandboxTemplate',
name: 'wpTemplateSandboxTemplate',
showMissing: false,
value: $input.val()
}),
{ label: 'Template name:' }
);
if (mw.loader.getState('ext.TemplateSandbox') !== 'registered') {
await mw.loader.using('mediawiki.widgets');
$input.parent().replaceWith(makeTemplateField().$element);
return;
}
let require = await mw.loader.using([
'ext.TemplateSandbox.TemplateSandboxTitleWidget',
'ext.TemplateSandbox.styles', 'jquery.makeCollapsible', 'user.options'
]);
let widget = new (require('ext.TemplateSandbox.TemplateSandboxTitleWidget'))({
$overlay: true,
id: 'wpTemplateSandboxPage',
maxLength: 255,
name: 'wpTemplateSandboxPage',
placeholder: 'Page title',
required: false,
tabIndex: 10,
templateTitleFunc: () => $('#wpTemplateSandboxTemplate').val()
});
widget.$element.attr('data-ooui', '{"_":"mw.widgets.TemplateSandboxTitleWidget"}')
.data('oouiInfused', widget);
let fieldset = new OO.ui.FieldsetLayout({
classes: ['mw-templatesandbox-fieldset', 'mw-collapsed'],
id: 'templatesandbox-editform',
items: [
makeTemplateField(),
new OO.ui.ActionFieldLayout(
widget,
new OO.ui.ButtonInputWidget({
id: 'wpTemplateSandboxPreview',
name: 'wpTemplateSandboxPreview',
label: 'Show preview',
tabIndex: 10,
type: 'submit',
useInputTag: true
}),
{ align: 'top' }
)
],
label: 'Preview page with this template'
});
fieldset.$label.append(' ', $('<span>').addClass('mw-collapsible-toggle-placeholder'));
fieldset.$group.addClass('mw-collapsible-content');
$('#templatesandbox-editform').replaceWith(fieldset.$element.makeCollapsible());
let modules = ['ext.TemplateSandbox'];
if (Number(mw.user.options.get('uselivepreview'))) {
modules.push('ext.TemplateSandbox.preview');
}
mw.loader.load(modules);
});
mw.config.get('wgWikiID') === 'enwiki' &&
mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist' &&
(async () => {
mw.loader.addStyleTag('.xfdnotifier-sublinks::before{content:" ["} .xfdnotifier-sublinks::after{content:"]"} .xfdnotifier-sublinks > span:not(:first-child)::before{content:"\\2009·\\2009"} .mw-portlet.vector-menu[id^="p-xfdnotifier-"] a{display:inline}');
await mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.storage']);
let xfds = [
{
id: 'rm',
label: 'RM',
full: 'Requested moves',
cat: 'Requested moves',
},
{
id: 'rmt',
label: 'RM/T',
full: 'Requested moves (technical)',
page: 'Wikipedia:Requested_moves/Technical_requests',
titleExtractor: $page => (
$page.find(`[data-mw*='"wt":"RMassist/core"']`).closest('li').map(function () {
return this.querySelector('a[rel="mw:WikiLink"]')?.title;
}).get()
)
},
{
id: 'afd',
label: 'AfD',
full: 'Articles for deletion',
cat: 'Articles for deletion'
},
{
id: 'mfd',
label: 'MfD',
full: 'Miscellaneous for deletion',
cat: 'Miscellaneous pages for deletion'
},
{
id: 'tfd',
label: 'TfD',
full: 'Templates for deletion',
cat: 'Templates for deletion'
},
{
id: 'tfm',
label: 'TfM',
full: 'Templates for merging',
cat: 'Templates for merging'
},
{
id: 'cfd',
label: 'CfD',
full: 'Categories for deletion',
cat: 'Categories for deletion'
},
{
id: 'cfr',
label: 'CfR',
full: 'Categories for renaming',
cat: 'Categories for renaming'
},
{
id: 'cfsr',
label: 'CfSR',
full: 'Categories for speedy renaming',
cat: 'Categories for speedy renaming'
},
{
id: 'cfm',
label: 'CfM',
full: 'Categories for merging',
cat: 'Categories for merging'
},
{
id: 'cfs',
label: 'CfS',
full: 'Categories for splitting',
cat: 'Categories for splitting'
},
{
id: 'cfl',
label: 'CfL',
full: 'Categories for listifying',
cat: 'Categories for listifying'
},
{
id: 'cfc',
label: 'CfC',
full: 'Categories for conversion',
cat: 'Categories for conversion'
},
{
id: 'cfgd',
label: 'CfGD',
full: 'Categories for general discussion',
cat: 'Categories for general discussion'
},
{
id: 'ffd',
label: 'FfD',
full: 'Files for discussion',
cat: 'Wikipedia files for discussion'
},
{
id: 'rfd',
label: 'RfD',
full: 'Redirects for discussion',
cat: 'All redirects for discussion'
},
{
id: 'prod',
label: 'PROD',
full: 'Articles proposed for deletion',
cat: 'All articles proposed for deletion'
}
];
window.xfd = xfds;
let queryTitles = async (xfd, titles) => {
if (!titles.length) return;
let response = await new mw.Api().get({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched) {
xfd.pages.push(p.title);
}
});
await queryTitles(xfd, titles.slice(50));
};
let queryPage = async xfd => {
let $page = $($.parseHTML(await $.get(
`https://en.wikipedia.org/w/rest.php/v1/page/${encodeURIComponent(xfd.page)}/html`
)));
await queryTitles(xfd, xfd.titleExtractor($page));
};
let queryCat = async (xfd, gcmcontinue) => {
let response = await new mw.Api().get({
action: 'query',
prop: 'info|categories',
inprop: 'watched',
clprop: 'sortkey',
clcategories: `Category:${xfd.cat}`,
generator: 'categorymembers',
gcmtitle: `Category:${xfd.cat}`,
gcmlimit: 'max',
gcmsort: 'timestamp',
gcmdir: 'older',
gcmcontinue: gcmcontinue,
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched && p.categories?.[0]?.sortkeyprefix !== ' ') {
xfd.pages.push(p.title);
}
});
if (response?.continue?.gcmcontinue) {
await queryCat(xfd, response.continue.gcmcontinue);
}
};
let show = async (xfd, lastId, isCache) => {
if (xfd.portlet && isCache) return;
let portletId = 'p-xfdnotifier-' + xfd.id;
if (xfd.portlet) {
$(xfd.portlet).find('ul').empty();
if (!xfd.pages.length) return;
} else {
await $.ready;
xfd.portlet = mw.util.addPortlet(portletId, xfd.label, '#' + lastId);
}
let $label = $(`#${portletId}-label`).attr('title', xfd.full);
if (xfd.page) {
$label.wrapInner($('<a>').attr('href', mw.util.getUrl(xfd.page)));
}
xfd.pages.forEach(p => {
let t = mw.Title.newFromText(p);
let isTalk = t.isTalkPage();
let $other = $('<a>').attr({
href: t[isTalk ? 'getSubjectPage' : 'getTalkPage']().getUrl(),
title: isTalk ? 'subject' : 'talk'
}).text(isTalk ? 's' : 't');
let link = mw.util.addPortletLink(portletId, t.getUrl(), p).querySelector('a');
$('<span>').addClass('xfdnotifier-sublinks').append(
$('<span>').append($other),
$('<span>').append(
$('<a>').attr({
href: t.getUrl({ action: 'history' }),
title: 'history'
}).text('h')
)
).insertAfter(link);
});
};
mw.hook('wikipage.content').add(mw.util.throttle(async () => {
let cache = mw.storage.getObject('xfdnotifier') || {};
let lastId = 'p-tb';
for (let xfd of xfds) {
let portletId = 'p-xfdnotifier-' + xfd.id;
let now = Math.floor(Date.now() / 1000);
if (now - cache[xfd.id]?.[0] < 600) {
xfd.pages = cache[xfd.id].slice(1);
await show(xfd, lastId, true);
lastId = portletId;
continue;
}
xfd.pages = [];
if (xfd.cat) {
await queryCat(xfd);
} else if (xfd.page) {
await queryPage(xfd);
}
cache[xfd.id] = [now, ...xfd.pages];
mw.storage.setObject('xfdnotifier', cache, 604800);
await show(xfd, lastId);
lastId = portletId;
}
}, 1800000));
})();
9j5mfd17bk8lqcmpk6o02qwgxw1iefn
735819
735818
2026-04-01T11:27:01Z
Nardog
40946
735819
javascript
text/javascript
(async function listTools() {
let pageAction = mw.config.get('wgAction');
let isView = pageAction === 'view';
let isEdit = ['edit', 'submit'].includes(pageAction);
if (!isView && !isEdit) return;
let pageType = mw.config.get('wgCanonicalSpecialPageName') ||
mw.config.get('wgNamespaceNumber');
if (isView && !pageType && !mw.config.exists('wgRedirectedFrom') &&
!mw.config.get('wgIsRedirect') &&
!mw.config.get('wgPageName').includes('/')
) {
return;
}
await mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api',
'mediawiki.interface.helpers.styles'
]);
mw.loader.addStyleTag(`.listtools:not(#mw-content-subtitle .listtools) {
font-size: 85%;
}
.listtools, .listtools a {
font-weight: normal !important;
font-style: normal;
}
.mw-datatable .listtools {
display: block;
}
.listtools + .mw-whatlinkshere-tools,
#watchlist-edit-form .listtools ~ .mw-changeslist-links,
.mw-special-DisambiguationPageLinks .listtools + a {
display: none;
}`);
let messages = Object.assign({
watched: 'Added "$1" to your watchlist',
watchFail: `Couldn't watch "$1"`,
unwatchFail: `Couldn't unwatch "$1"`
}, window.listtoolsMessages);
let getMsg = (key, ...args) => (
Object.hasOwn(messages, key) ? mw.format(messages[key], ...args) : key
);
let notif;
let watchHandler = async function (e) {
e.preventDefault();
let $link = $(this);
let $wrapper = $link.parent();
$link.detach();
let params = new URLSearchParams(this.search);
let action = params.get('action');
$wrapper.text(getMsg(action + 'ing'));
let pn = params.get('title').replaceAll('_', ' ');
let promise = new mw.Api()[action](pn);
if (notif) {
notif.close();
notif = null;
}
try {
let result = await promise;
if (!result || !result[action + 'ed']) throw '';
let newAction = action === 'watch' ? 'unwatch' : 'watch';
params.set('action', newAction);
$link.add(`.listtools-watch > a[href="${this.pathname + this.search}"]`)
.attr('href', this.pathname + '?' + params)
.text(getMsg(newAction));
if (action !== 'watch') return;
let require = await mw.loader.using([
'mediawiki.notification', 'mediawiki.watchstar.widgets'
]);
notif = await mw.notify(
new (require('mediawiki.watchstar.widgets'))('watch', pn, null, $.noop, {
message: getMsg('watched', pn)
}).$element,
{ tag: 'listtools' }
);
} catch {
notif = await mw.notify(getMsg(action + 'Fail', pn), {
tag: 'listtools',
type: 'error'
});
} finally {
$wrapper.html($link);
}
};
let extGetMain = function () {
return this.title;
};
let re = new RegExp(`(?:\\?title=|${
mw.util.escapeRegExp(mw.format(mw.config.get('wgArticlePath'), ''))
})([^#&?]+)`);
let processed = new WeakSet();
let processLinks = ($links, module, titles) => {
let isBatch = !!titles;
titles = titles || new Set();
$links.each(function (i) {
if (processed.has(this)) return;
let $link = $links.eq(i);
let pn;
if (module.useText) {
pn = $link.text();
} else {
let match = $link.attr('href')?.match(re);
if (!match) return;
pn = decodeURIComponent(match[1]);
}
let t = mw.Title.newFromText(pn);
if (!t) return;
if (module.titlesOnly) {
let text = $link.text();
if (text !== pn.replaceAll('_', ' ') &&
(text !== t.getMainText() || t.namespace === 2)
) {
return;
}
}
if ($link.is('.external, .extiw')) {
Object.assign(t, {
getMain: extGetMain,
host: this.host,
namespace: 0,
title: pn
});
} else {
if (t.namespace < 0) return;
if ($link.hasClass('new')) {
t.missing = true;
}
titles.add(t.getSubjectPage().toText());
}
let $tools = $('<span>').addClass('listtools mw-changeslist-links')
.data('listtools', t);
tools.forEach(tool => {
addTool($tools, tool);
});
if ($link.is(':is(del, bdi) > :only-child')) {
if (module.position === 'end') {
$link.parent().parent().append(' ', $tools);
} else {
$link.parent().after(' ', $tools);
}
} else if (module.position === 'end') {
$link.parent().append(' ', $tools);
} else {
$link.after(' ', $tools);
}
if (module.post) {
module.post($tools);
}
processed.add(this);
});
if (!isBatch) {
getWatched(titles);
}
};
let tools = [
{
name: 'edit',
url: t => t.getUrl({ action: 'edit' })
},
{
name: 'hist',
url: t => !t.missing && t.getUrl({ action: 'history' })
},
{
name: 'links',
url: t => mw.util.getUrl('Special:WhatLinksHere/' + t)
},
{
name: 'watch',
url: t => !t.host && t.getSubjectPage().getUrl({ action: 'watch' }),
callback: watchHandler
}
];
let addTool = ($tools, tool, escapedName) => {
let t = $tools.data('listtools');
let $duplicate = escapedName &&
$tools.children('.listtools-' + escapedName);
let url = tool.url;
if (typeof url === 'function') {
url = url(t);
if (!url) {
$duplicate?.remove();
return;
}
}
let $link = $('<a>').attr('href', url).text(getMsg(tool.name));
if (t.host) {
$link.prop('host', t.host);
}
if (tool.callback) {
$link.on('click', tool.callback);
}
let $wrapper = $('<span>').addClass('listtools-' + tool.name)
.append($link);
let $next = tool.next && $tools.children('.listtools-' + tool.next);
if ($next?.length) {
$duplicate?.remove();
$next.before($wrapper);
} else if ($duplicate?.length) {
$duplicate.replaceWith($wrapper);
} else {
$tools.append($wrapper);
}
};
let extend = tool => {
if (tool.label && !Object.hasOwn(messages, tool.label)) {
messages[tool.name] = tool.label;
}
if (tool.next) {
tool.next = $.escapeSelector(tool.next);
}
let existingTool = tools.find(t => t.name === tool.name);
if (existingTool) {
Object.assign(existingTool, tool);
} else {
tools.push(tool);
}
let escapedName = existingTool && $.escapeSelector(tool.name);
let $allTools = $('.listtools');
$allTools.each(function (i) {
addTool($allTools.eq(i), tool, escapedName);
});
};
let getWatched = async titles => {
if (!Array.isArray(titles)) {
titles = [...titles].slice(0, 500);
}
if (!titles.length) return;
(await new mw.Api().post({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages.forEach(page => {
if (!page.watched) return;
$(`.listtools-watch > a[href="${mw.util.getUrl(page.title, { action: 'watch' })}"]`)
.attr('href', mw.util.getUrl(page.title, { action: 'unwatch' }))
.text(getMsg('unwatch'));
});
getWatched(titles.slice(50));
};
mw.hook('listtools.ready').fire(extend);
let catTreeCallback = (records, observer) => {
let $links = $(records[0].target).find('.CategoryTreeItem > bdi > a');
if ($links.length) {
observer.takeRecords();
observer.disconnect();
processLinks($links, catTreeModule);
}
};
let catTreeModule = {
selector: '.CategoryTreeItem > bdi > a',
types: [14, 'CategoryTree'],
position: 'end',
post: $tools => {
$tools.parent().next('.CategoryTreeChildren').each(function () {
new MutationObserver(catTreeCallback)
.observe(this, { childList: true });
});
}
};
let modules = [
{
selector: '#mw-pages li > a, #mw-pages li > span > a',
types: [14]
},
catTreeModule,
{
selector: '#mw-imagepage-section-linkstoimage a, #mw-imagepage-section-globalusage a',
types: [6]
},
{
selector: '#mw-globalusage-result a',
types: ['GlobalUsage']
},
{
selector: '.mw-search-result-heading > a, .searchalttitle > a.mw-redirect, .iw-result__title > a, .mw-search-exists a',
types: ['Search']
},
{
selector: '.mw-search-createlink a',
types: ['Search'],
titlesOnly: true
},
{
selector: '#watchlist-edit-form .cdx-table td > label > a',
types: ['EditWatchlist']
},
{
selector: '.plainlinks > li > a',
types: ['AbuseLog'],
titlesOnly: true
},
{
selector: '#mw-allmessagestable td:first-child > a:first-child:not(.new)',
types: ['Allmessages'],
position: 'end'
},
{
selector: '.mw-spcontent li a',
types: ['DisambiguationPageLinks', 'Listredirects'],
titlesOnly: true
},
{
selector: 'li > a:first-child',
types: ['FileDuplicateSearch']
},
{
selector: '.TablePager_col_title > a:first-child, .TablePager_col_template > a',
types: ['LintErrors'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: 'form > ul > li > a',
types: ['Nuke'],
position: 'end',
titlesOnly: true
},
{
selector: '.page-assessments a',
types: ['PageAssessments'],
titlesOnly: true
},
{
selector: '.TablePager_col_pr_page > a',
types: ['Protectedpages'],
position: 'end'
},
{
selector: '#mw-content-text > ul a',
types: ['Protectedtitles'],
position: 'end'
},
{
selector: '.mw-fr-pending-changes-page-title',
types: ['PendingChanges'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: '#mw-content-text > ul a:first-child',
types: ['StablePages'],
position: 'end'
},
{
selector: '.TablePager_col__page a',
types: ['TopicSubscriptions']
},
{
selector: '.undeleteResult > a',
types: ['Undelete'],
position: 'end',
useText: true
},
{
selector: '.TablePager_col_img_name > a:first-child',
// types: ['Listfiles'],
position: 'end'
},
{
selector: '.mw-newpages-pagename',
post: $tools => {
let $contents = $tools.parent().contents();
$contents.slice(
$contents.index($tools) + 1,
$contents.index($contents.filter('.mw-newpages-length'))
).replaceWith(' ');
}
},
{
selector: '#mw-whatlinkshere-list li > bdi > a'
},
{
selector: '.mw-changeslist-log-entry > a:not(.mw-changeslist-log-gblblock a, .mw-changeslist-log-globalauth a)',
titlesOnly: true
},
{
selector: '.mw-logevent-loglines > li:not(.mw-logline-gblblock, .mw-logline-globalauth) > a',
types: ['Log'],
titlesOnly: true
},
{
selector: '#mw-diff-otitle1 > strong > a, #mw-diff-ntitle1 > strong > a',
types: ['ComparePages'],
position: 'end'
},
{
selector: '#movepage-oldlink, #movepage-newlink',
types: ['Movepage']
},
{
selector: '.mw-undelete-revision a:not(.mw-userlink, .mw-usertoollinks > a)',
types: ['Undelete'],
useText: true
},
{
selector: '.galleryfilename, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner-comment > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-enhanced-rc-nested > .comment > a'
},
{
selector: '.mw-spcontent li a',
position: 'end',
titlesOnly: true
}
];
if (isEdit) {
let post = $tools => {
if (!$tools[0].closest('.templatesUsed')) return;
$tools.parent().contents().last().each(function () {
this.textContent = this.textContent.slice(1);
}).end().slice(-3, -1).remove();
};
let callback = mw.util.debounce(() => {
processLinks(
$('.mw-editfooter-list a, #wikiPreview > .previewnote a'),
{ titlesOnly: true, post }
);
}, 500);
mw.hook('wikipage.editform').add($form => {
callback();
$form.find('.templatesUsed').each(function () {
if (processed.has(this)) return;
processed.add(this);
new MutationObserver(callback)
.observe(this, { childList: true, subtree: true });
});
});
} else if (typeof pageType === 'number') {
$(() => {
processLinks($('.subpages a, .mw-redirectedfrom a, .redirectText a'), {});
});
}
mw.hook('wikipage.content').add($content => {
let titles = new Set();
let $links = $content.find('a');
modules.forEach(module => {
if (module.types && !module.types.includes(pageType)) return;
processLinks($links.filter(module.selector), module, titles);
});
getWatched(titles);
});
}());
mw.hook('listtools.ready').add(extend => {
// extend({
// name: 'talk',
// url: t => !t.isTalkPage() && t.canHaveTalkPage() && t.getTalkPage().getUrl(),
// next: 'hist'
// });
extend({
name: 'subject',
url: t => t.isTalkPage() && t.getSubjectPage().getUrl(),
next: 'hist'
});
extend({
name: 'last',
url: t => !t.missing && t.getUrl({ diff: 'cur', diffonly: 1 }),
next: 'links'
});
// extend({
// name: 'purge',
// url: t => t.getUrl({ action: 'purge' }),
// next: 'watch',
// callback: function (e) {
// e.preventDefault();
// let $link = $(this);
// let $wrapper = $link.parent();
// $link.detach();
// $wrapper.text('purging');
// let pn = $wrapper.closest('.listtools').data('listtools').toText();
// new mw.Api().post({
// action: 'purge',
// forcelinkupdate: 1,
// titles: pn,
// formatversion: 2
// }).then(response => {
// if (response.purge[0].purged) {
// mw.notify(`Purged "${pn}"'`);
// }
// }).always(() => {
// $wrapper.html($link);
// });
// }
// });
extend({
name: 'copy',
url: '#',
callback: function (e) {
e.preventDefault();
let text = $(this).closest('.listtools').data('listtools').toText();
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch (err) {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
}
});
});
(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
mw.config.get('wgCanonicalSpecialPageName') !== 'GlobalContributions' &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector += ', ' + this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i + 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i + 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes += ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i + '/' + count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 + ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 + ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());
if (mw.config.get('wgNamespaceNumber') === 14 && (
mw.config.get('wgAction') === 'view' || !mw.config.get('wgArticleId')
)) {
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox8.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.DateFormatter',
'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget', 'mediawiki.widgets.datetime',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-movement',
'mediawiki.interface.helpers.styles', 'user.options'
]);
}
$(function moveHistory() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Move history', 't-movehistory').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.moveHistoryDialog) {
window.moveHistoryDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox5.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.Title', 'mediawiki.DateFormatter',
'oojs-ui-windows', 'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.DateInputWidget', 'oojs-ui.styles.icons-interactions',
'mediawiki.interface.helpers.styles'
]);
});
});
});
$(function sectionSearch() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Section search', 't-sectionsearch').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.sectionSearchDialog) {
window.sectionSearchDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox7.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-windows',
'mediawiki.widgets', 'mediawiki.widgets.NamespacesMultiselectWidget'
]);
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'CentralAuth' &&
mw.loader.using('jquery.tablesorter', function sortCentralAuthByEditCount() {
mw.hook('wikipage.content').add($content => {
let $table = $content.find('.mw-centralauth-wikislist').has('td');
if (!$table.length) return;
$table.tablesorter().data('tablesorter').sort([{ 4: 'desc' }, { 1: 'asc' }]);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
[10, 828].includes(mw.config.get('wgNamespaceNumber')) &&
!mw.config.get('wgTitle').endsWith('/doc') &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/AutoTestcases.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/TemplatePreviewGuard.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// $(function templatePreviewGuard() {
// let button = document.querySelector('input[name="wpTemplateSandboxPreview"]');
// if (!button) return;
// let proceed;
// button.addEventListener('click', e => {
// if (proceed) {
// proceed = false;
// return;
// }
// e.preventDefault();
// e.stopPropagation();
// let formData = new FormData(button.form);
// let page = formData.get('wpTemplateSandboxPage');
// let temp = formData.get('wpTemplateSandboxTemplate');
// if (!page || !temp) return;
// mw.loader.using('mediawiki.api').then(() => (
// new mw.Api().get({
// action: 'query',
// titles: page,
// prop: 'templates',
// tltemplates: temp,
// formatversion: 2
// })
// )).always(response => {
// if (((((response || {}).query || {}).pages || [])[0] || {}).templates ||
// confirm(`"${page}" doesn't appear to transclude "${temp}". Continue?`)
// ) {
// proceed = true;
// button.click();
// }
// });
// }, true);
// if (!mw.config.get('wgArticleId')) return;
// let widgetEl = document.querySelector('#wpTemplateSandboxPage.oo-ui-widget');
// if (!widgetEl) return;
// let pn = mw.config.get('wgPageName').replace(/_/g, ' ');
// mw.loader.using(['mediawiki.api', 'oojs-ui-core']).then(() => (
// new mw.Api().get({
// action: 'query',
// titles: pn,
// prop: 'transcludedin',
// tiprop: 'title',
// tilimit: 'max',
// formatversion: 2
// })
// )).then(response => {
// if (!response.batchcomplete) return;
// let pages = response.query.pages[0].transcludedin
// .filter(o => o.title !== pn);
// if (!pages.length) return;
// let widget = OO.ui.infuse(widgetEl);
// if (pages.length === 1) {
// widget.setValue(pages[0].title);
// return;
// }
// widget.$element.replaceWith(
// new OO.ui.ComboBoxInputWidget({
// id: 'wpTemplateSandboxPage',
// maxlength: widget.$input.prop('maxLength'),
// name: widget.$input.prop('name'),
// options: pages
// .sort((a, b) => a.ns - b.ns || -(a.title < b.title))
// .map(o => ({ data: o.title })),
// placeholder: widget.$input.prop('placeholder'),
// tabIndex: widget.getTabIndex(),
// value: widget.getValue()
// }).on('enter', e => {
// e.preventDefault();
// button.click();
// }).$element
// );
// });
// });
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(async () => {
let form = document.getElementById('editform');
if (!form) return;
let formData = new FormData(form);
let section = formData.get('wpSection');
if (section === 'new') return;
let widget = document.getElementById('wpSummaryWidget');
if (!widget) return;
let isOld = formData.get('altBaseRevId') > 0 ||
(formData.get('baseRevId') || formData.get('parentRevId')) !== formData.get('editRevId');
await mw.loader.using([
'jquery.textSelection', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core',
'oojs-ui.styles.icons-editing-core'
]);
let $textarea = $('#wpTextbox1');
let input = OO.ui.infuse(widget);
let button = new OO.ui.ButtonWidget({
framed: false,
icon: 'undo',
classes: ['autosectionlink-button'],
invisibleLabel: true,
label: 'Restore previous section link'
}).toggle().on('click', () => {
let cache = button.getData();
input.setValue(input.getValue().replace(
/^(\/\*.*?\*\/)?\s*/,
cache[0] ? '/* ' + cache[0] + ' */ ' : ''
));
updatePreview(cache[0]);
cache.reverse();
}).on('toggle', () => {
input.$input.css('width', `calc(100% - ${button.$element.width()}px)`);
});
input.$input.after(button.$element);
let update = mw.util.debounce($diff => {
let lines = $textarea.textSelection('getContents').trimEnd().split('\n');
let firstLineNum;
if (isOld) {
let i, lastLineNum;
$diff.find('td:last-child').each(function () {
if (this.classList.contains('diff-lineno')) {
i = this.textContent.replace(/\D+/g, '') - 1;
} else if (this.classList.contains('diff-context')) {
i++;
} else if (this.classList.contains('diff-addedline')) {
i++;
if (!firstLineNum) {
firstLineNum = i;
}
lastLineNum = i;
} else if (this.classList.contains('diff-empty')) {
if (!firstLineNum) {
firstLineNum = i === 0 ? 1 : i;
}
lastLineNum = i;
}
});
lines.length = lastLineNum || 0;
} else {
let origLines = $textarea.prop('defaultValue').trimEnd().split('\n');
firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
if (!firstLineNum) {
firstLineNum = lines.length < origLines.length
? lines.length
: 1;
}
for (let i = 1, x = lines.length, y = origLines.length;
(section ? i < x : i <= x) && lines[x - i] === origLines[y - i];
i++
) {
lines.pop();
}
}
let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 7;
lines.slice(firstLineNum).forEach(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
lowest = match[1].length;
}
});
let head;
lines.slice(0, firstLineNum).reverse().some(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
head = match[2];
return true;
}
});
head = head ? head
.replace(/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
.replace(/''(.+?)''/g, '$1')
.trim() : null;
let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
let prev = match[1];
if (section < 1 && lowest === 7 && !head) {
head = '';
}
if (prev === head) return;
input.setValue((typeof head === 'string' ? '/* ' + head + ' */ ' : '') + match[2]);
button.setData([prev, head]).toggle(true);
updatePreview(head);
}, 500);
let updatePreview = head => {
let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
if (!$preview.length) return;
let hasHead = typeof head === 'string';
let url = hasHead && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
let text = hasHead && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + (head || mw.messages.get('autocomment-top', '(top)'));
let $ac = $preview.children('.autocomment:first-child');
if ($ac.length && !$ac[0].previousSibling) {
if (hasHead) {
$ac.children('a').attr('href', url).text(text);
} else {
let node = $ac[0].nextSibling;
if (node?.nodeType === 3) {
node.textContent = node.textContent.trimStart();
}
$ac.remove();
}
} else if (hasHead) {
$('<span>').addClass('autocomment').append(
$('<a>').attr({
href: url,
title: mw.config.get('wgPageName').replace(/_/g, ' ')
}).text(text),
mw.messages.get('colon-separator', ': ')
).prependTo($preview);
}
};
if (isOld) {
mw.hook('wikipage.diff').add(update);
} else {
$textarea.on('input', update);
mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
if (on && $codeMirror[0].CodeMirror) {
$codeMirror[0].CodeMirror.on('change', update);
}
});
mw.hook('ext.CodeMirror.input').add(update);
update();
}
new mw.Api().loadMessagesIfMissing(['autocomment-top', 'colon-separator']);
mw.loader.addStyleTag('.autosectionlink-button{position:absolute;top:0;right:0;margin:0}');
});
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(function copyRevId() {
let handler = function (e) {
e.preventDefault();
let text = this.closest('.diff td')?.querySelector('[data-mw-revid]')?.dataset.mwRevid ||
this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!text) return;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
document.execCommand('copy');
$input.remove();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id')
)
);
});
}());
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(() => {
let handler = async function (e) {
e.preventDefault();
let td = this.closest('.diff td');
let rev = td
? td.querySelector('[data-mw-revid]')?.dataset.mwRevid
: this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!rev) {
mw.notify(`Couldn't get the revision.`, {
tag: 'markasunseen',
type: 'error'
});
return;
}
let pn = td
? new URLSearchParams([...td.querySelectorAll('a')].pop()?.search).get('title')
: mw.config.get('wgPageName');
if (!pn) return;
await mw.loader.using('mediawiki.api');
let result = (await new mw.Api().postWithEditToken({
action: 'setnotificationtimestamp',
[td ? 'newerthanrevid' : 'torevid']: rev,
titles: pn,
formatversion: 2
})).setnotificationtimestamp?.[0];
if (Object.hasOwn(result, 'notificationtimestamp')) {
mw.notify(`Marked revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'success'
});
} else if (result?.notwatched) {
mw.notify('This page is not on your watchlist.', {
tag: 'markasunseen',
type: 'warn'
});
} else {
mw.notify(`Couldn't mark revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'error'
});
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions after this one as unseen'
}).on('click', handler).text('unseen'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions since this one as unseen'
}).on('click', handler).text('unseen')
)
);
});
})();
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
((mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4) ||
(mw.config.get('wgWikiID') === 'metawiki' && mw.config.get('wgPageContentModel') === 'wikitext')) &&
mw.loader.using(['mediawiki.util', 'mediawiki.Title'], function copyUnsig() {
let handler = function (e) {
e.preventDefault();
let parent = this.closest('li, td');
let ts = parent.textContent.match(/\d\d:\d\d, \d\d? [A-Z][a-z]+ \d{4}/)?.[0];
if (!ts) return;
let user = parent.querySelector('.mw-userlink').textContent;
if (mw.util.isIPv6Address(user)) {
user = user.toUpperCase();
}
let temp = mw.util.isIPAddress(user) ? 'unsigned IP' : 'unsigned';
let text = `{{subst:${temp}|${user}|${ts}}}`;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').filter(function () {
if (mw.config.get('wgWikiID') === 'metawiki') {
return true;
}
let link = this.querySelector('strong > a') ||
this.parentElement.querySelector('#differences-prevlink, #differences-nextlink');
if (!link) return;
let t = mw.Title.newFromText(mw.util.getParamValue('title', link.search));
return t.isTalkPage() || t.namespace === 4;
}).append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig')
)
);
});
});
// mw.config.get('wgAction') === 'history' &&
// mw.loader.using('mediawiki.util', function () {
// mw.hook('wikipage.content').add($content => {
// $content.find('a.mw-changeslist-date').after(function () {
// return [
// ' (',
// $('<a>').attr('href', mw.util.getUrl(null, {
// action: 'edit',
// oldid: this.closest('li').dataset.mwRevid
// })).text('e'),
// ')'
// ];
// });
// });
// });
// ['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
// mw.hook('wikipage.content').add($content => {
// $content.find('.mw-changeslist-history').parent().after(function () {
// return $('<span>').append(
// $('<a>').attr(
// 'href',
// this.firstElementChild.getAttribute('href').slice(0, -7) + 'edit'
// ).text('e')
// );
// });
// });
if (screen.width < 500) {
mw.loader.addStyleTag('@font-face{font-family:CharisW;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/017b2b2ad86e09d3c22b8cf0dfc78247/CharisSILRegular.ttf) format(truetype)} @font-face{font-family:CharisW;font-weight:700;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/6f5069ac6a300dad45383c952e92c573/CharisSILBold.ttf) format(truetype)} body .IPA{font-family:CharisW,sans-serif} .mw-highlight-lines > pre{width:120em}');
location.hash && $(() => {
let target = document.querySelector(':target');
if (target?.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
});
}
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
(mw.config.exists('wgCodeEditorCurrentLanguage') ||
mw.config.exists('cmMode') && mw.config.get('cmMode') !== 'mediawiki') &&
(function saveNEdit() {
let notif;
$(document.body).on('click', '#wpSave', async function (e) {
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey ||
e.originalEvent?.defaultPrevented
) {
return;
}
e.preventDefault();
await mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'jquery.textSelection', 'oojs-ui-core'
]);
let button = OO.ui.infuse(this.parentElement).setDisabled(true);
let $textarea = $('#wpTextbox1');
let text = $textarea.textSelection('getContents');
let $summary = $('#wpSummary');
let formData = new FormData(this.form);
let promise = new mw.Api().postWithEditToken({
action: 'edit',
title: mw.config.get('wgPageName'),
text: text,
section: formData.get('wpSection') || undefined,
summary: $summary.textSelection('getContents'),
[$('#wpMinoredit').prop('checked') ? 'minor' : 'notminor']: 1,
baserevid: formData.get('editRevId'),
basetimestamp: formData.get('wpEdittime'),
starttimestamp: formData.get('wpStarttime'),
watchlist: $('#wpWatchthis').prop('checked') ? 'watch' : 'unwatch',
watchlistexpiry: formData.get('wpWatchlistExpiry') || undefined,
undo: formData.get('wpUndidRevision') || undefined,
undoafter: formData.get('wpUndoAfter') || undefined,
contentformat: formData.get('format'),
contentmodel: formData.get('model'),
assertuser: mw.config.get('wgUserName'),
formatversion: 2
});
notif?.close();
notif = null;
try {
let response = await promise;
if (response?.edit?.result !== 'Success') throw '';
$('#editform > input[name="wpUndidRevision"], #editform > input[name="wpUndoAfter"]').remove();
$textarea.data('origtext', text).prop('defaultValue', text);
$summary.val($summary.prop('defaultValue'));
if (mw.loader.getState('mediawiki.editRecovery.edit') === 'ready') {
let storage = mw.loader.moduleRegistry['mediawiki.editRecovery.edit'].packageExports['storage.js'];
storage.deleteData(mw.config.get('wgPageName'));
storage.closeDatabase();
}
notif = await mw.notify(response.edit.nochange ? 'No change' : [
document.createTextNode('Saved'),
$('<p>').append(
new OO.ui.ButtonWidget({
href: mw.util.getUrl(),
target: '_blank',
label: 'View'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, {
diff: response.edit.newrevid || 'cur',
diffonly: 1
}),
target: '_blank',
label: 'Diff'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, { action: 'history' }),
target: '_blank',
label: 'History'
}).$element
)[0]
], { tag: 'savenedit' });
} catch (error) {
notif = await mw.notify(error?.error?.info || error || 'Save failed', {
autoHideSeconds: 'long',
tag: 'savenedit',
type: 'error'
});
} finally {
button.setDisabled();
}
});
}());
mw.config.get('wgNamespaceNumber') === 0 &&
mw.config.get('wgAction') === 'view' &&
mw.config.get('wgCategories')?.some(c => c.endsWith(' actors') || c.endsWith(' actresses')) &&
$(() => {
let n = $.escapeSelector(mw.config.get('wgTitle').replace(/ \(.+\)$/, ''));
let $links = $(`.hatnote a[title$="${n} filmography"], .hatnote a[title*="${n} on "], .hatnote a[title*="${n} performances"]`);
if (!$links.length) return;
let titles = {};
$links = $links.filter(function () {
let text = this.textContent;
return !(titles[text] = Object.hasOwn(titles, text));
});
mw.notify(
$links.length === 1
? $links.clone()
: $('<ul>').append($links.clone().wrap('<li>').parent()),
{ autoHideSeconds: 'long' }
);
});
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
let os = mw.user.options.get('userjs-rcmuter');
let set = new Set(os && os.split('|'));
let save = () => {
let ns = [...set].join('|');
if (ns === mw.user.options.get('userjs-rcmuter')) return;
new mw.Api().saveOption('userjs-rcmuter', ns);
mw.user.options.set('userjs-rcmuter', ns);
$edit.attr('data-rcmuter', set.size);
};
mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
let $edit = $('<a>').attr({
class: 'rcmuter-edit',
href: '#',
'data-rcmuter': set.size
}).text('Edit muted').on('click', e => {
e.preventDefault();
mw.loader.using([
'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
let multiselect = new mw.widgets.UsersMultiselectWidget({
$overlay: dialog.$overlay,
ipAllowed: true,
selected: [...set]
}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
let instance = dialog.open({
message: $([
document.createTextNode('Muted users:'),
multiselect.$element[0]
]),
size: 'medium'
});
instance.opened.then(() => {
setTimeout(() => {
multiselect.focus().menu.toggle(false);
});
});
instance.closed.then(result => {
if (!result || result.action !== 'accept') return;
set = new Set(multiselect.getSelectedUsernames());
save();
mw.notify('Changes will take effect in next load.', {
tag: 'rcmuter'
});
});
});
});
let buttonsShown;
let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
e.preventDefault();
if (buttonsShown) {
mw.hook('wikipage.content').remove(addButtons);
$('.rcmuter-toggle').remove();
this.textContent = 'Show toggle buttons';
} else {
mw.hook('wikipage.content').add(addButtons);
this.textContent = 'Hide toggle buttons';
}
buttonsShown = !buttonsShown;
});
let $toggle = $('<a>').attr({
class: 'rcmuter-togglemuted',
href: '#'
}).text('Show muted').on('click', function (e) {
e.preventDefault();
this.textContent = document.body.classList.toggle('rcmuter-disabled')
? 'Hide muted'
: 'Show muted';
});
let $toggleSpan = $('<span>').hide().append($toggle);
mw.util.addSubtitle(
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append($edit),
$('<span>').append($toggleButtons),
$toggleSpan
)[0]
);
let toggle = function (e) {
e.preventDefault();
let user = $(this)
.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
.last().text().trim();
if (!user) {
mw.notify(`Can't retrieve the username.`, {
tag: 'rcmuter',
type: 'error'
});
return;
}
let muting = this.parentElement.classList.toggle('rcmuter-unmute');
set[muting ? 'add' : 'delete'](user);
save();
this.textContent = muting ? 'unmute' : 'mute';
mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
tag: 'rcmuter'
});
};
let addButtons = $content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) {
$content = $('#mw-content-text');
if ($content.has('.rcmuter-toggle').length) return;
}
let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
let $muted = $tools.filter('.rcmuter-muted *');
$tools.not($muted).append(
$('<span>').addClass('rcmuter-toggle').append(
$('<a>').attr('href', '#').text('mute').on('click', toggle)
)
);
if (!$muted.length) return;
$muted.append(
$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
$('<a>').attr('href', '#').text('unmute').on('click', toggle)
)
);
};
let mutedCount;
let filter = function () {
let muted = set.has(this.textContent);
if (muted) mutedCount++;
return muted;
};
mw.hook('wikipage.content').add($content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) return;
if (!set.size) {
$toggleSpan.hide();
return;
}
mutedCount = 0;
$content.find('.changedby > .mw-userlink:only-child')
.filter(filter).closest('table').addClass('rcmuter-muted');
$content.find('.mw-userlink:not(.changedby > *, .comment *, .rcmuter-muted *)')
.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
$toggleSpan.toggle(!!mutedCount);
$toggle.attr('data-rcmuter', mutedCount);
});
});
location.hostname.endsWith('.wikipedia.org') &&
mw.config.get('wgNamespaceNumber') % 2 === 0 &&
// mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.util')).then(function refRenamer() {
if (!document.getElementById('p-tb')) return;
let messages = Object.assign({
portlet: 'RefRenamer',
loading: 'Loading RefRenamer...'
}, window.refrenamerMessages);
let clicked;
mw.util.addPortletLink('p-tb', '#', messages.portlet, 't-refrenamer').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.refRenamer) {
window.refRenamer();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox6.js&action=raw&ctype=text/javascript');
mw.notify(messages.loading, {
autoHideSeconds: 'long',
tag: 'refrenamer'
});
});
});
if (['edit', 'submit'].includes(mw.config.get('wgAction'))) {
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/ExpandContractions.js&action=raw&ctype=text/javascript', 's');
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/Unpipe.js&action=raw&ctype=text/javascript', 's');
}
mw.config.get('wgAction') !== 'history' &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/CopyCodeBlock.js&action=raw&ctype=text/javascript', 's');
mw.config.exists('wgDiffNewId') &&
mw.config.get('wgDiscussionToolsFeaturesEnabled') &&
(function () {
let data = {}, clickHandler, autoClear, run;
window.dtc = data;
let highlight = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
mw.loader.moduleRegistry['ext.discussionTools.init'].packageExports['highlighter.js']
.highlightNewComments(mw.dt.pageThreads, true, ids);
if (clickHandler) {
$(document.body).off('click', clickHandler);
return;
}
$._data(document.body, 'events').click.some(o => {
if (String(o.handler).includes('highlighter.clearHighlightTargetComment(')) {
$(document.body).off('click', o.handler);
clickHandler = o.handler;
return true;
}
});
$._data(window, 'events').popstate.some(o => {
if (String(o.handler).includes('highlighter.highlightTargetComment(')) {
$(window).off('popstate', o.handler);
return true;
}
});
};
let scroll = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
let yToSpan = Object.fromEntries(
ids.map(id => document.getElementById(id)).filter(Boolean)
.map(span => [span.getBoundingClientRect().y, span])
);
let ys = Object.keys(yToSpan);
if (!ys.length) return;
let lower = ys.filter(y => y > 10);
if (!lower.length ||
Math.max(...lower) < document.documentElement.clientHeight
) {
yToSpan[Math.min(...ys)].scrollIntoView();
} else {
yToSpan[Math.min(...lower)].scrollIntoView();
}
};
let scrollToNext = function (e) {
e.preventDefault();
let revId = mw.config.get('wgDiffOldId');
if (!revId || !data[revId]) return;
let i = data[revId].indexOf(
this.closest('[data-mw-thread-id]').dataset.mwThreadId
);
if (i === -1) return;
let next = data[revId][i + 1] || data[revId][0];
document.getElementById(next).scrollIntoView();
};
mw.hook('wikipage.content').add(async $content => {
let revId = mw.config.get('wgDiffOldId');
if (!revId) return;
let param = new URLSearchParams(location.search).get('diffonly');
if (param && param !== '0') return;
if (data[revId]) {
highlight(revId);
return;
}
await mw.loader.using(['ext.discussionTools.init', 'mediawiki.util']);
let begin = Date.parse($('#mw-diff-otitle1 .mw-diff-timestamp').data('timestamp'));
data[revId] = mw.dt.pageThreads.getCommentItems()
.filter(c => c.timestamp > begin).map(c => c.id);
if (!data[revId].length) return;
await new Promise(setTimeout);
highlight(revId);
$content.find('.ext-discussiontools-init-replylink-buttons').filter(function () {
return data[revId].includes(this.dataset.mwThreadId);
}).children('span:last-of-type').before(
' | ',
$('<a>').attr({
href: '#',
role: 'button'
}).text('next').on('click', scrollToNext)
);
if (run || !document.getElementById('p-tb')) return;
run = true;
let portlet = mw.util.addPortletLink('p-tb', '#', 'Scroll to next', 't-scrolltonext');
portlet.firstElementChild.addEventListener('click', e => {
e.preventDefault();
scroll(mw.config.get('wgDiffOldId'));
});
mw.util.addPortletLink('p-tb', '#', 'Toggle highlight', 't-togglehighlight').firstElementChild.addEventListener('click', e => {
e.preventDefault();
autoClear = !autoClear;
if (autoClear) {
$(document.body).on('click', clickHandler)[0].click();
} else {
highlight(mw.config.get('wgDiffOldId'));
}
});
mw.loader.addStyleTag(`#t-scrolltonext{position:fixed;bottom:${portlet.clientHeight}px} #t-togglehighlight{position:fixed;bottom:0}`);
});
}());
mw.config.get('wgNamespaceNumber') === 6 &&
mw.config.get('wgAction') === 'view' &&
mw.hook('wikipage.content').add($content => {
$content.find('.filehistory .mw-usertoollinks-contribs').after(function () {
return [
' | ',
$('<a>').attr('href', `${
mw.config.get('wgScript')
}?title=Special:ListFiles/${
this.pathname.replace(/^.+\//, '')
}&ilshowall=1`).text('uploads')
];
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function () {
if (!$('input[name="wpSection"]').val()) return;
mw.hook('wikipage.content').add(async $content => {
let $refs = $content.find('.mw-ext-cite-warning-sectionpreview_no_text');
if (!$refs.length) return;
let ids = {};
$refs.each(function () {
ids[this.closest('[id]').id.replace(/-\d+$/, '')] = this;
});
let response = await $.get(`/api/rest_v1/page/html/${encodeURIComponent(mw.config.get('wgPageName'))}`);
$($.parseHTML(response)).find('.mw-reference-text').each(function () {
ids[this.id.replace(/^mw-reference-text-|-\d+$/g, '')]?.replaceWith(this);
});
});
});
mw.hook('moremenu.ready').add(config => {
$('#mm-page-purge-cache > a').on('click', e => {
e.preventDefault();
new mw.Api().post({
action: 'purge',
forcelinkupdate: 1,
titles: config.page.name,
formatversion: 2
}).then(() => {
location.href = mw.util.getUrl();
});
});
$('#mm-page-search-search-history-wikiblame > a').on('click', function (e) {
e.preventDefault();
let q = prompt();
if (q === null) return;
let href = this.href;
if (q) {
let removal = q[0] === '!';
if (removal) {
q = q.slice(1);
}
href += '&needle=' + encodeURIComponent(q);
if (removal) {
href += '&binary_search_inverse=on';
}
href += '&force_wikitags=on';
}
open(href, '_blank');
});
$('#mm-page-expand-templates > a').on('click auxclick', function (e) {
if (e.which > 2) return;
e.preventDefault();
let revId = mw.config.get('wgRevisionId') || Number($('input[name=oldid]').val());
let url = revId
? '/w/rest.php/v1/revision/' + revId
: '/w/rest.php/v1/page/' + config.page.encodedName;
$.get(url).then(response => {
$('<form>').attr({
method: 'post',
action: this.href,
target: '_blank'
}).append(
[
['wpInput', response.source],
['wpContextTitle', config.page.name],
['wpRemoveComments', 1]
].map(([n, v]) => $('<input>').attr({
name: n,
type: 'hidden'
}).val(v))
).appendTo(document.body).trigger('submit').remove();
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'ApiSandbox' &&
mw.hook('apisandbox.formatRequest').add((...args) => {
args[4].complete = function () {
setTimeout(() => {
mw.hook('wikipage.content').fire($('.oo-ui-pageLayout-active'));
}, 100);
};
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.storage')).then(async () => {
let infuseAndCall = (query, method, ...args) => {
let $widget = $(query);
if ($widget.length) {
return OO.ui.infuse($widget)[method](...args);
}
};
let section = $('input[name="wpSection"]').val();
if (section) {
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let save = () => {
let newSource = $textarea.textSelection('getContents');
if (newSource === source) {
mw.storage.session.remove('editfullpage');
} else {
mw.storage.session.setObject('editfullpage', [
mw.config.get('wgPageName'),
section,
newSource.trimEnd(),
infuseAndCall('#wpSummaryWidget', 'getValue') || '',
Number(infuseAndCall('#wpMinoreditWidget', 'isSelected')) || 0,
Number(infuseAndCall('#wpWatchthisWidget', 'isSelected')) || 0,
infuseAndCall('#wpWatchlistExpiryWidget', 'getValue') || 'infinite'
]);
}
};
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
setInterval(() => {
mw.requestIdleCallback(save);
}, 3000);
window.addEventListener('beforeunload', save);
return;
}
let data = mw.storage.session.getObject('editfullpage');
mw.storage.session.remove('editfullpage');
console.log(data);
if (!data || data[0] !== mw.config.get('wgPageName')) return;
let isNew = data[1] === 'new';
let isLead = data[1] === '0';
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let newSource, start, msg, notifOpts = { autoHideSeconds: 'long' };
let orig = [];
if (isNew) {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
newSource = source + (data[3] ? '\n== ' + data[3] + ' ==\n\n' : '\n') + data[2] + '\n';
start = source.length;
} else {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core', 'mediawiki.api']);
let { parse } = await new mw.Api().get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
wrapoutputclass: '',
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
formatversion: 2
});
let target = !isLead && parse.sections.find(s => s.index === data[1]);
if (isLead || target) {
let next = parse.sections.find(s => s.index - 1 === Number(data[1]));
newSource = (isLead ? '' : [...source].slice(0, target.byteoffset)).join('') +
data[2] + (next ? '\n\n' + [...source].slice(next.byteoffset).join('') : '\n');
start = isLead ? 0 : target.byteoffset;
} else {
newSource = source + '\n\n' + data[2] + '\n';
start = source.length;
msg = `Section restored. Couldn't find the section. The source is appended at bottom.`;
notifOpts.type = 'warn';
}
orig[0] = infuseAndCall('#wpSummaryWidget', 'getValue');
infuseAndCall('#wpSummaryWidget', 'setValue', data[3]);
}
$textarea.textSelection('setContents', newSource);
orig[1] = infuseAndCall('#wpMinoreditWidget', 'getSelected');
infuseAndCall('#wpMinoreditWidget', 'setSelected', data[4]);
orig[2] = infuseAndCall('#wpWatchthisWidget', 'getSelected');
infuseAndCall('#wpWatchthisWidget', 'setSelected', data[5]);
orig[3] = infuseAndCall('#wpWatchlistExpiryWidget', 'getValue');
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', data[6]);
setTimeout(() => {
$textarea.textSelection('setSelection', { start });
});
let notif = await mw.notify($([
document.createTextNode(msg || 'Section restored.'),
$('<p>').append(
new OO.ui.ButtonWidget({
flags: 'destructive',
label: 'Discard'
}).on('click', () => {
$textarea.textSelection('setContents', source);
if (orig[0]) {
infuseAndCall('#wpSummaryWidget', 'setValue', orig[0]);
}
infuseAndCall('#wpMinoreditWidget', 'setSelected', orig[1]);
infuseAndCall('#wpWatchthisWidget', 'setSelected', orig[2]);
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', orig[3]);
notif.close();
}).$element
)[0]
]), notifOpts);
});
mw.config.exists('wgPostEdit') &&
mw.loader.using('mediawiki.storage', () => {
mw.storage.session.remove('editfullpage');
});
mw.config.get('wgAction') === 'history' &&
mw.hook('wikipage.content').add(async $content => {
if (!$content.has('.mw-history-line-updated').length) return;
let href = $content.find('a.mw-history-histlinks-current:not(.mw-history-line-updated a)').attr('href');
if (!href) {
await mw.loader.using(['mediawiki.api', 'mediawiki.util']);
let page = (await new mw.Api().get({
action: 'query',
titles: mw.config.get('wgPageName'),
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev >= page.lastrevid) return;
href = mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
}
$content.find('.mw-history-compareselectedversions-button').first().after(
' ',
$('<a>').attr({
class: 'unseendiff',
href: href
}).text('unseen')
);
});
(async () => {
let cspn = mw.config.get('wgCanonicalSpecialPageName');
let isBp = cspn === 'Blankpage';
if (!isBp && cspn !== 'Watchlist') return;
await mw.loader.using('mediawiki.util');
let notify = async (text, options, pn) => {
let msg = [document.createTextNode(text)];
if (pn) {
msg.push(
$('<p>').append(
$('<a>').attr('href', mw.util.getUrl(pn)).text(pn),
' ',
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'edit' }))
.text('edit')
),
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'history' }))
.text('history')
)
)
)[0]
);
}
if (isBp) {
await $.ready;
$('#mw-content-text').html(msg);
} else {
return mw.notify(msg, Object.assign(options || {}, {
tag: 'unseendiff'
}));
}
};
let getUrl = async pn => {
await mw.loader.using('mediawiki.api');
let page = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
if (!page.notificationtimestamp) {
notify(`Couldn't get the last seen time.`, {
type: 'warn'
}, pn);
return;
}
let rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (rev === page.lastrevid) {
notify('Already seen.', {
type: 'warn'
}, pn);
return;
}
if (!rev) {
rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
rvdir: 'newer',
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev) {
notify(`Couldn't get the last seen revision.`, {
type: 'warn'
}, pn);
return;
}
}
if (rev > page.lastrevid) {
notify(`Invalid rev for "${pn}" (rev: ${rev}, lastrevid: ${page.lastrevid})`, {
autoHideSeconds: 'long',
type: 'warn'
}, pn);
return;
}
return mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
};
if (isBp) {
let pn = mw.config.get('wgTitle').match(/^[^/]+\/unseendiff\/(.+)$/)?.[1];
if (!pn) return;
notify('Loading...', null, pn);
let href = await getUrl(pn);
if (!href) return;
notify('Redirecting...', null, pn);
location.href = href;
return;
}
let handler = async function (e) {
if (e.which > 2) return;
e.preventDefault();
let pn = this.dataset.pn;
if (!pn) {
notify(`Couldn't get the page name.`, {
type: 'error'
});
return;
}
let notifPromise = notify('Loading...', {
autoHideSeconds: 'long'
});
let href = await getUrl(pn);
if (!href) return;
$(`.unseendiff-loader[data-pn="${$.escapeSelector(pn)}"]`).attr({
class: 'unseendiff',
href: href,
target: '_blank'
}).off('click auxclick', handler);
if (e.type === 'auxclick' || e.ctrlKey || e.metaKey || e.shiftKey) {
open(href);
} else {
this.click();
}
(await notifPromise).close();
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-changeslist-src-mw-edit.mw-changeslist-watchedunseen:not(.mw-changeslist-watchedseen) .mw-changeslist-line-inner'
).each(function () {
let pn = this.dataset.targetPage ||
this.closest('[data-target-page]')?.dataset.targetPage ||
this.closest('table.mw-enhanced-rc')?.querySelector('[data-target-page]')?.dataset.targetPage;
if (!pn) return;
$('<span>').append(
$('<a>').attr({
class: 'unseendiff-loader',
href: mw.util.getUrl(`Special:BlankPage/unseendiff/${pn}`),
'data-pn': pn
}).on('click auxclick', handler).text('unseen')
).appendTo(
[...this.querySelectorAll('.mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
});
})();
['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
mw.loader.using('mediawiki.util', () => {
let watched = new Set();
let query = async lis => {
let titles = Object.keys(lis).slice(0, 50);
if (!titles.length) return;
await mw.loader.using('mediawiki.api');
let pages = (await new mw.Api().post({
action: 'query',
titles: titles,
prop: 'info',
inprop: 'notificationtimestamp|watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages;
for (let page of pages) {
if (!Object.hasOwn(lis, page.title)) continue;
if (page.watched) {
watched.add(page);
$(lis[page.title]).addClass('watched');
}
if (!page.notificationtimestamp) continue;
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev === page.lastrevid) continue;
if (rev > page.lastrevid) {
mw.notify($([
document.createTextNode('Invalid rev for "'),
$('<a>').attr({
href: mw.util.getUrl(page.title, { action: 'history' }),
target: '_blank'
}).text(page.title)[0],
document.createTextNode(`" (rev: ${rev}, lastrevid: ${page.lastrevid})`),
]), {
autoHideSeconds: 'long',
type: 'warn'
});
continue;
}
$('<span>').append(
$('<a>').attr({
class: 'unseendiff',
href: mw.util.getUrl(page.title, {
diff: page.lastrevid,
oldid: rev
})
}).text('unseen')
).appendTo(
lis[page.title].map(li => (
[...li.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(li).before(' ')
))
);
}
titles.forEach(title => {
delete lis[title];
});
query(lis);
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-contributions-list > li:not(.mw-contributions-current)[data-mw-revid]'
).each(function () {
let link = this.querySelector('a.mw-changeslist-date, a.mw-changeslist-history');
let pn = link ? new URLSearchParams(link.search).get('title') : '';
$('<span>').append(
$('<a>').attr({
class: 'mw-changeslist-diff',
href: mw.util.getUrl(pn, {
diff: 'cur',
oldid: this.dataset.mwRevid
})
}).text('cur')
).appendTo(
[...this.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
if (mw.config.get('wgWikiID') === 'wikidatawiki') return;
let lis = {};
$content.find('.mw-contributions-title').each(function () {
let title = this.textContent;
if (!Object.hasOwn(lis, title)) {
lis[title] = [];
}
lis[title].push(this.closest('li'));
});
Object.keys(lis).forEach(title => {
if (watched.has(title)) {
$(lis[title]).addClass('watched');
delete lis[title];
}
});
query(lis);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox9.js&action=raw&ctype=text/javascript');
mw.config.get('wgWikiID') === 'metawiki' &&
(async () => {
let css = mw.loader.addStyleTag(`.wishtitle {
font-size: 90%;
font-style: italic;
word-break: break-word;
}
.wishtitle > a {
color: var(--color-warning, #886425);
}
.wishtitle > a:visited {
color: var(--border-color-warning--hover, #735421);
}
.wishtitle-declined > a {
text-decoration: line-through;
}
.wishtitle-declined > a:hover,
.wishtitle-declined > a:focus,
.mw-underline-always .wishtitle-declined > a {
text-decoration: line-through underline;
}
#watchlist-edit-form .wishtitle {
display: inline-block;
}
.mw-search-result-heading > .wishtitle,
.catchangesviewer-table .wishtitle {
display: block;
}
.catchangesviewer-table:has(.wishtitle) {
white-space: wrap;
}`);
let lang = mw.config.get('wgUserLanguage');
let titles;
let loadTitles = async () => {
await mw.loader.using('mediawiki.storage');
titles = titles || mw.storage.getObject('wishtitles');
if (titles?.lang !== lang) {
titles = { lang, w: [], fa: [] };
}
};
let updateTitles = async (crwstatuses, crwcontinue) => {
await mw.loader.using('mediawiki.api');
let params = {
action: 'query',
list: 'communityrequests-wishes',
crwlang: lang,
crwstatuses: crwstatuses,
crwprop: 'title|updated',
crwsort: 'updated',
crwdir: 'ascending',
crwlimit: 'max',
crwcontinue: crwcontinue,
formatversion: 2
};
if (!crwcontinue && !crwstatuses && titles._) {
params.crwcontinue = `|${titles._}|0`;
}
let response = await new mw.Api().get(params);
let wishes = response?.query?.['communityrequests-wishes'];
if (wishes?.length) {
let $span = $('<span>');
wishes.forEach(w => {
let id = w.crwtitle.match(/^Community Wishlist\/W(\d+)/)?.[1];
if (!id) return;
titles.w[id - 1] = $span.html(w.title).text();
if (crwstatuses === 'declined') {
(titles.wd = titles.wd || []).push(id - 1);
}
let faId = w.crfatitle?.match(/^Community Wishlist\/FA(\d+)/)?.[1];
if (!faId) return;
titles.fa[faId - 1] = w.focusareatitle;
});
if (!crwstatuses) {
titles._ = wishes.at(-1).updated.replace(/\D/g, '');
}
}
let expiry = 86400;
if (crwstatuses || crwcontinue) {
let prev = mw.storage.getObject('_EXPIRY_wishtitles');
if (prev) {
expiry = Math.round(Date.now() / 1000) + 86400 - prev;
}
}
mw.storage.setObject('wishtitles', titles, expiry);
crwcontinue = response?.continue?.crwcontinue;
if (crwcontinue) {
await updateTitles(crwstatuses, crwcontinue);
}
};
let getTitle = id => (
id[0] === 'W' ? titles.w[id.slice(1) - 1] : titles.fa[id.slice(2) - 1]
);
let renderTitle = (title, id, tag = 'span') => {
let classes = 'wishtitle';
if (id[0] === 'W' && titles.wd?.includes(id.slice(1) - 1)) {
classes += ' wishtitle-declined';
}
return $(`<${tag}>`).addClass(classes).append(
$('<a>').attr({
href: `/wiki/Community_Wishlist/${id}`,
title: `Community Wishlist/${id}`
}).text(title)
);
};
let callback = ([id, links]) => {
let title = getTitle(id);
if (!title) {
return true;
}
$(links).after(' ', renderTitle(title, id));
};
let selector = '.mw-changeslist-title, ' +
'.mw-changeslist-log-entry > a:not(.mw-userlink), ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize :is(.mw-changeslist-line-inner, .mw-changeslist-line-inner-comment, .mw-enhanced-rc-nested) > .comment > a, ' +
'#watchlist-edit-form .cdx-table td > label > a, ' +
'.mw-search-result-heading > a:not(:has(> .ext-communityrequests-entity-link--label)), ' +
'.mw-contributions-title, ' +
'#mw-whatlinkshere-list li > bdi > a, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-logevent-loglines > li > a, ' +
'#mw-pages li > a, ' +
'.catchangesviewer-table td:nth-child(3) > a';
mw.hook('wikipage.content').add(async $content => {
let links = {};
$content.find('a').each(function () {
if (!this.matches(selector)) return;
let id = this.textContent.match(
/^(?:Talk:|Translations:)?Community Wishlist\/((?:W|FA)\d+)/
)?.[1];
if (!id) return;
(links[id] = links[id] || []).push(this);
});
links = Object.entries(links);
if (!links.length) return;
await loadTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles('declined');
links.forEach(callback);
});
let pn = mw.config.get('wgRelevantPageName');
let id = pn.match(/^(?:Talk:|Translations:)?Community_Wishlist\/((?:W|FA)\d+)/)?.[1];
if (!id) return;
await $.ready;
let extTitle = document.querySelector('.ext-communityrequests-wish--title');
if (extTitle && $('.mw-pt-languages-selected').attr('lang') === lang) return;
await loadTitles();
let title = getTitle(id);
if (!title) {
await updateTitles();
title = getTitle(id);
if (!title) {
await updateTitles('declined');
title = getTitle(id);
if (!title) return;
}
}
let $title = renderTitle(title, id, 'div');
if (mw.config.get('skin') === 'vector-2022') {
$title.prependTo('.vector-page-toolbar');
} else {
$title.insertAfter('#firstHeading');
}
css.textContent += ' .ext-communityrequests-entity-talk-header{display:none}';
if (extTitle) return;
document.title = document.title.replace(
pn.replaceAll('_', ' '),
`${pn.replace(`Community_Wishlist/${id}`, title)} ($&)`
);
})();
mw.config.get('wgWikiID') === 'metawiki' &&
mw.hook('wikipage.watchlistChange').add(async (isWatched, expiry) => {
if (![0, 1].includes(mw.config.get('wgNamespaceNumber'))) return;
let title = mw.config.get('wgTitle');
if (!/^Community Wishlist\/(?:W|FA)\d+$/.test(title)) return;
if (isWatched) {
await new mw.Api().watch(title + '/Votes', expiry);
mw.notify('Watching /Votes too.');
} else {
await new mw.Api().unwatch(title + '/Votes');
mw.notify('Unwatched /Votes too.');
}
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
$(async () => {
let $input = $('#wpTemplateSandboxTemplate');
if (!$input.length) return;
mw.loader.addStyleTag('#templatesandbox-editform .oo-ui-fieldLayout{max-width:50em} #templatesandbox-editform .oo-ui-fieldLayout-field{flex-grow:999}');
let makeTemplateField = () => new OO.ui.FieldLayout(
new mw.widgets.TitleInputWidget({
inputId: 'wpTemplateSandboxTemplate',
name: 'wpTemplateSandboxTemplate',
showMissing: false,
value: $input.val()
}),
{ label: 'Template name:' }
);
if (mw.loader.getState('ext.TemplateSandbox') !== 'registered') {
await mw.loader.using('mediawiki.widgets');
$input.parent().replaceWith(makeTemplateField().$element);
return;
}
let require = await mw.loader.using([
'ext.TemplateSandbox.TemplateSandboxTitleWidget',
'ext.TemplateSandbox.styles', 'jquery.makeCollapsible', 'user.options'
]);
let widget = new (require('ext.TemplateSandbox.TemplateSandboxTitleWidget'))({
$overlay: true,
id: 'wpTemplateSandboxPage',
maxLength: 255,
name: 'wpTemplateSandboxPage',
placeholder: 'Page title',
required: false,
tabIndex: 10,
templateTitleFunc: () => $('#wpTemplateSandboxTemplate').val()
});
widget.$element.attr('data-ooui', '{"_":"mw.widgets.TemplateSandboxTitleWidget"}')
.data('oouiInfused', widget);
let fieldset = new OO.ui.FieldsetLayout({
classes: ['mw-templatesandbox-fieldset', 'mw-collapsed'],
id: 'templatesandbox-editform',
items: [
makeTemplateField(),
new OO.ui.ActionFieldLayout(
widget,
new OO.ui.ButtonInputWidget({
id: 'wpTemplateSandboxPreview',
name: 'wpTemplateSandboxPreview',
label: 'Show preview',
tabIndex: 10,
type: 'submit',
useInputTag: true
}),
{ align: 'top' }
)
],
label: 'Preview page with this template'
});
fieldset.$label.append(' ', $('<span>').addClass('mw-collapsible-toggle-placeholder'));
fieldset.$group.addClass('mw-collapsible-content');
$('#templatesandbox-editform').replaceWith(fieldset.$element.makeCollapsible());
let modules = ['ext.TemplateSandbox'];
if (Number(mw.user.options.get('uselivepreview'))) {
modules.push('ext.TemplateSandbox.preview');
}
mw.loader.load(modules);
});
mw.config.get('wgWikiID') === 'enwiki' &&
mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist' &&
(async () => {
mw.loader.addStyleTag('.xfdnotifier-sublinks::before{content:" ["} .xfdnotifier-sublinks::after{content:"]"} .xfdnotifier-sublinks > span:not(:first-child)::before{content:"\\2009·\\2009"} .mw-portlet.vector-menu[id^="p-xfdnotifier-"] a{display:inline}');
await mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.storage']);
let xfds = [
{
id: 'rm',
label: 'RM',
full: 'Requested moves',
cat: 'Requested moves',
},
{
id: 'rmt',
label: 'RM/T',
full: 'Requested moves (technical)',
page: 'Wikipedia:Requested_moves/Technical_requests',
titleExtractor: $page => (
$page.find(`[data-mw*='"wt":"RMassist/core"']`).closest('li').map(function () {
return this.querySelector('a[rel="mw:WikiLink"]')?.title;
}).get()
)
},
{
id: 'afd',
label: 'AfD',
full: 'Articles for deletion',
cat: 'Articles for deletion'
},
{
id: 'mfd',
label: 'MfD',
full: 'Miscellaneous for deletion',
cat: 'Miscellaneous pages for deletion'
},
{
id: 'tfd',
label: 'TfD',
full: 'Templates for deletion',
cat: 'Templates for deletion'
},
{
id: 'tfm',
label: 'TfM',
full: 'Templates for merging',
cat: 'Templates for merging'
},
{
id: 'cfd',
label: 'CfD',
full: 'Categories for deletion',
cat: 'Categories for deletion'
},
{
id: 'cfr',
label: 'CfR',
full: 'Categories for renaming',
cat: 'Categories for renaming'
},
{
id: 'cfsr',
label: 'CfSR',
full: 'Categories for speedy renaming',
cat: 'Categories for speedy renaming'
},
{
id: 'cfm',
label: 'CfM',
full: 'Categories for merging',
cat: 'Categories for merging'
},
{
id: 'cfs',
label: 'CfS',
full: 'Categories for splitting',
cat: 'Categories for splitting'
},
{
id: 'cfl',
label: 'CfL',
full: 'Categories for listifying',
cat: 'Categories for listifying'
},
{
id: 'cfc',
label: 'CfC',
full: 'Categories for conversion',
cat: 'Categories for conversion'
},
{
id: 'cfgd',
label: 'CfGD',
full: 'Categories for general discussion',
cat: 'Categories for general discussion'
},
{
id: 'ffd',
label: 'FfD',
full: 'Files for discussion',
cat: 'Wikipedia files for discussion'
},
{
id: 'rfd',
label: 'RfD',
full: 'Redirects for discussion',
cat: 'All redirects for discussion'
},
{
id: 'prod',
label: 'PROD',
full: 'Articles proposed for deletion',
cat: 'All articles proposed for deletion'
}
];
window.xfd = xfds;
let queryTitles = async (xfd, titles) => {
if (!titles.length) return;
let response = await new mw.Api().get({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched) {
xfd.pages.push(p.title);
}
});
await queryTitles(xfd, titles.slice(50));
};
let queryPage = async xfd => {
let $page = $($.parseHTML(await $.get(
`https://en.wikipedia.org/w/rest.php/v1/page/${encodeURIComponent(xfd.page)}/html`
)));
await queryTitles(xfd, xfd.titleExtractor($page));
};
let queryCat = async (xfd, gcmcontinue) => {
let response = await new mw.Api().get({
action: 'query',
prop: 'info|categories',
inprop: 'watched',
clprop: 'sortkey',
clcategories: `Category:${xfd.cat}`,
generator: 'categorymembers',
gcmtitle: `Category:${xfd.cat}`,
gcmlimit: 'max',
gcmsort: 'timestamp',
gcmdir: 'older',
gcmcontinue: gcmcontinue,
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched && p.categories?.[0]?.sortkeyprefix !== ' ') {
xfd.pages.push(p.title);
}
});
if (response?.continue?.gcmcontinue) {
await queryCat(xfd, response.continue.gcmcontinue);
}
};
let show = async (xfd, lastId, isCache) => {
if (xfd.portlet && isCache) return;
let portletId = 'p-xfdnotifier-' + xfd.id;
if (xfd.portlet) {
$(xfd.portlet).find('ul').empty();
if (!xfd.pages.length) return;
} else {
await $.ready;
xfd.portlet = mw.util.addPortlet(portletId, xfd.label, '#' + lastId);
}
let $label = $(`#${portletId}-label`).attr('title', xfd.full);
if (xfd.page) {
$label.wrapInner($('<a>').attr('href', mw.util.getUrl(xfd.page)));
}
xfd.pages.forEach(p => {
let t = mw.Title.newFromText(p);
let isTalk = t.isTalkPage();
let $other = $('<a>').attr({
href: t[isTalk ? 'getSubjectPage' : 'getTalkPage']().getUrl(),
title: isTalk ? 'subject' : 'talk'
}).text(isTalk ? 's' : 't');
let link = mw.util.addPortletLink(portletId, t.getUrl(), p).querySelector('a');
$('<span>').addClass('xfdnotifier-sublinks').append(
$('<span>').append($other),
$('<span>').append(
$('<a>').attr({
href: t.getUrl({ action: 'history' }),
title: 'history'
}).text('h')
)
).insertAfter(link);
});
};
mw.hook('wikipage.content').add(mw.util.throttle(async () => {
let cache = mw.storage.getObject('xfdnotifier') || {};
let lastId = 'p-tb';
for (let xfd of xfds) {
let portletId = 'p-xfdnotifier-' + xfd.id;
let now = Math.floor(Date.now() / 1000);
if (now - cache[xfd.id]?.[0] < 600) {
xfd.pages = cache[xfd.id].slice(1);
await show(xfd, lastId, true);
lastId = portletId;
continue;
}
xfd.pages = [];
if (xfd.cat) {
await queryCat(xfd);
} else if (xfd.page) {
await queryPage(xfd);
}
cache[xfd.id] = [now, ...xfd.pages];
mw.storage.setObject('xfdnotifier', cache, 604800);
await show(xfd, lastId);
lastId = portletId;
}
}, 1800000));
})();
cwmzso971drnym27sbfhm9y4m76hvyg
735820
735819
2026-04-01T11:29:44Z
Nardog
40946
735820
javascript
text/javascript
(async function listTools() {
let pageAction = mw.config.get('wgAction');
let isView = pageAction === 'view';
let isEdit = ['edit', 'submit'].includes(pageAction);
if (!isView && !isEdit) return;
let pageType = mw.config.get('wgCanonicalSpecialPageName') ||
mw.config.get('wgNamespaceNumber');
if (isView && !pageType && !mw.config.exists('wgRedirectedFrom') &&
!mw.config.get('wgIsRedirect') &&
!mw.config.get('wgPageName').includes('/')
) {
return;
}
await mw.loader.using([
'mediawiki.util', 'mediawiki.Title', 'mediawiki.api',
'mediawiki.interface.helpers.styles'
]);
mw.loader.addStyleTag(`.listtools:not(#mw-content-subtitle .listtools) {
font-size: 85%;
}
.listtools, .listtools a {
font-weight: normal !important;
font-style: normal;
}
.mw-datatable .listtools {
display: block;
}
.listtools + .mw-whatlinkshere-tools,
#watchlist-edit-form .listtools ~ .mw-changeslist-links,
.mw-special-DisambiguationPageLinks .listtools + a {
display: none;
}`);
let messages = Object.assign({
watched: 'Added "$1" to your watchlist',
watchFail: `Couldn't watch "$1"`,
unwatchFail: `Couldn't unwatch "$1"`
}, window.listtoolsMessages);
let getMsg = (key, ...args) => (
Object.hasOwn(messages, key) ? mw.format(messages[key], ...args) : key
);
let notif;
let watchHandler = async function (e) {
e.preventDefault();
let $link = $(this);
let $wrapper = $link.parent();
$link.detach();
let params = new URLSearchParams(this.search);
let action = params.get('action');
$wrapper.text(getMsg(action + 'ing'));
let pn = params.get('title').replaceAll('_', ' ');
let promise = new mw.Api()[action](pn);
if (notif) {
notif.close();
notif = null;
}
try {
let result = await promise;
if (!result || !result[action + 'ed']) throw '';
let newAction = action === 'watch' ? 'unwatch' : 'watch';
params.set('action', newAction);
$link.add(`.listtools-watch > a[href="${this.pathname + this.search}"]`)
.attr('href', this.pathname + '?' + params)
.text(getMsg(newAction));
if (action !== 'watch') return;
let require = await mw.loader.using([
'mediawiki.notification', 'mediawiki.watchstar.widgets'
]);
notif = await mw.notify(
new (require('mediawiki.watchstar.widgets'))('watch', pn, null, $.noop, {
message: getMsg('watched', pn)
}).$element,
{ tag: 'listtools' }
);
} catch {
notif = await mw.notify(getMsg(action + 'Fail', pn), {
tag: 'listtools',
type: 'error'
});
} finally {
$wrapper.html($link);
}
};
let extGetMain = function () {
return this.title;
};
let re = new RegExp(`(?:\\?title=|${
mw.util.escapeRegExp(mw.format(mw.config.get('wgArticlePath'), ''))
})([^#&?]+)`);
let processed = new WeakSet();
let processLinks = ($links, module, titles) => {
let isBatch = !!titles;
titles = titles || new Set();
$links.each(function (i) {
if (processed.has(this)) return;
let $link = $links.eq(i);
let pn;
if (module.useText) {
pn = $link.text();
} else {
let match = $link.attr('href')?.match(re);
if (!match) return;
pn = decodeURIComponent(match[1]);
}
let t = mw.Title.newFromText(pn);
if (!t) return;
if (module.titlesOnly) {
let text = $link.text();
if (text !== pn.replaceAll('_', ' ') &&
(text !== t.getMainText() || t.namespace === 2)
) {
return;
}
}
if ($link.is('.external, .extiw')) {
Object.assign(t, {
getMain: extGetMain,
host: this.host,
namespace: 0,
title: pn
});
} else {
if (t.namespace < 0) return;
if ($link.hasClass('new')) {
t.missing = true;
}
titles.add(t.getSubjectPage().toText());
}
let $tools = $('<span>').addClass('listtools mw-changeslist-links')
.data('listtools', t);
tools.forEach(tool => {
addTool($tools, tool);
});
if ($link.is(':is(del, bdi) > :only-child')) {
if (module.position === 'end') {
$link.parent().parent().append(' ', $tools);
} else {
$link.parent().after(' ', $tools);
}
} else if (module.position === 'end') {
$link.parent().append(' ', $tools);
} else {
$link.after(' ', $tools);
}
if (module.post) {
module.post($tools);
}
processed.add(this);
});
if (!isBatch) {
getWatched(titles);
}
};
let tools = [
{
name: 'edit',
url: t => t.getUrl({ action: 'edit' })
},
{
name: 'hist',
url: t => !t.missing && t.getUrl({ action: 'history' })
},
{
name: 'links',
url: t => mw.util.getUrl('Special:WhatLinksHere/' + t)
},
{
name: 'watch',
url: t => !t.host && t.getSubjectPage().getUrl({ action: 'watch' }),
callback: watchHandler
}
];
let addTool = ($tools, tool, escapedName) => {
let t = $tools.data('listtools');
let $duplicate = escapedName &&
$tools.children('.listtools-' + escapedName);
let url = tool.url;
if (typeof url === 'function') {
url = url(t);
if (!url) {
$duplicate?.remove();
return;
}
}
let $link = $('<a>').attr('href', url).text(getMsg(tool.name));
if (t.host) {
$link.prop('host', t.host);
}
if (tool.callback) {
$link.on('click', tool.callback);
}
let $wrapper = $('<span>').addClass('listtools-' + tool.name)
.append($link);
let $next = tool.next && $tools.children('.listtools-' + tool.next);
if ($next?.length) {
$duplicate?.remove();
$next.before($wrapper);
} else if ($duplicate?.length) {
$duplicate.replaceWith($wrapper);
} else {
$tools.append($wrapper);
}
};
let extend = tool => {
if (tool.label && !Object.hasOwn(messages, tool.label)) {
messages[tool.name] = tool.label;
}
if (tool.next) {
tool.next = $.escapeSelector(tool.next);
}
let existingTool = tools.find(t => t.name === tool.name);
if (existingTool) {
Object.assign(existingTool, tool);
} else {
tools.push(tool);
}
let escapedName = existingTool && $.escapeSelector(tool.name);
let $allTools = $('.listtools');
$allTools.each(function (i) {
addTool($allTools.eq(i), tool, escapedName);
});
};
let getWatched = async titles => {
if (!Array.isArray(titles)) {
titles = [...titles].slice(0, 500);
}
if (!titles.length) return;
(await new mw.Api().post({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages.forEach(page => {
if (!page.watched) return;
$(`.listtools-watch > a[href="${mw.util.getUrl(page.title, { action: 'watch' })}"]`)
.attr('href', mw.util.getUrl(page.title, { action: 'unwatch' }))
.text(getMsg('unwatch'));
});
getWatched(titles.slice(50));
};
mw.hook('listtools.ready').fire(extend);
let catTreeCallback = (records, observer) => {
let $links = $(records[0].target).find('.CategoryTreeItem > bdi > a');
if ($links.length) {
observer.takeRecords();
observer.disconnect();
processLinks($links, catTreeModule);
}
};
let catTreeModule = {
selector: '.CategoryTreeItem > bdi > a',
types: [14, 'CategoryTree'],
position: 'end',
post: $tools => {
$tools.parent().next('.CategoryTreeChildren').each(function () {
new MutationObserver(catTreeCallback)
.observe(this, { childList: true });
});
}
};
let modules = [
{
selector: '#mw-pages li > a, #mw-pages li > span > a',
types: [14]
},
catTreeModule,
{
selector: '#mw-imagepage-section-linkstoimage a, #mw-imagepage-section-globalusage a',
types: [6]
},
{
selector: '#mw-globalusage-result a',
types: ['GlobalUsage']
},
{
selector: '.mw-search-result-heading > a, .searchalttitle > a.mw-redirect, .iw-result__title > a, .mw-search-exists a',
types: ['Search']
},
{
selector: '.mw-search-createlink a',
types: ['Search'],
titlesOnly: true
},
{
selector: '#watchlist-edit-form .cdx-table td > label > a',
types: ['EditWatchlist']
},
{
selector: '.plainlinks > li > a',
types: ['AbuseLog'],
titlesOnly: true
},
{
selector: '#mw-allmessagestable td:first-child > a:first-child:not(.new)',
types: ['Allmessages'],
position: 'end'
},
{
selector: '.mw-spcontent li a',
types: ['DisambiguationPageLinks', 'Listredirects'],
titlesOnly: true
},
{
selector: 'li > a:first-child',
types: ['FileDuplicateSearch']
},
{
selector: '.TablePager_col_title > a:first-child, .TablePager_col_template > a',
types: ['LintErrors'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: 'form > ul > li > a',
types: ['Nuke'],
position: 'end',
titlesOnly: true
},
{
selector: '.page-assessments a',
types: ['PageAssessments'],
titlesOnly: true
},
{
selector: '.TablePager_col_pr_page > a',
types: ['Protectedpages'],
position: 'end'
},
{
selector: '#mw-content-text > ul a',
types: ['Protectedtitles'],
position: 'end'
},
{
selector: '.mw-fr-pending-changes-page-title',
types: ['PendingChanges'],
post: $tools => {
$tools.parent().contents().slice(3).remove();
}
},
{
selector: '#mw-content-text > ul a:first-child',
types: ['StablePages'],
position: 'end'
},
{
selector: '.TablePager_col__page a',
types: ['TopicSubscriptions']
},
{
selector: '.undeleteResult > a',
types: ['Undelete'],
position: 'end',
useText: true
},
{
selector: '.TablePager_col_img_name > a:first-child',
// types: ['Listfiles'],
position: 'end'
},
{
selector: '.mw-newpages-pagename',
post: $tools => {
let $contents = $tools.parent().contents();
$contents.slice(
$contents.index($tools) + 1,
$contents.index($contents.filter('.mw-newpages-length'))
).replaceWith(' ');
}
},
{
selector: '#mw-whatlinkshere-list li > bdi > a'
},
{
selector: '.mw-changeslist-log-entry > a:not(.mw-changeslist-log-gblblock a, .mw-changeslist-log-globalauth a)',
titlesOnly: true
},
{
selector: '.mw-logevent-loglines > li:not(.mw-logline-gblblock, .mw-logline-globalauth) > a',
types: ['Log'],
titlesOnly: true
},
{
selector: '#mw-diff-otitle1 > strong > a, #mw-diff-ntitle1 > strong > a',
types: ['ComparePages'],
position: 'end'
},
{
selector: '#movepage-oldlink, #movepage-newlink',
types: ['Movepage']
},
{
selector: '.mw-undelete-revision a:not(.mw-userlink, .mw-usertoollinks > a)',
types: ['Undelete'],
useText: true
},
{
selector: '.galleryfilename, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-changeslist-line-inner-comment > .comment > a, ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize .mw-enhanced-rc-nested > .comment > a'
},
{
selector: '.mw-spcontent li a',
position: 'end',
titlesOnly: true
}
];
if (isEdit) {
let post = $tools => {
if (!$tools[0].closest('.templatesUsed')) return;
$tools.parent().contents().last().each(function () {
this.textContent = this.textContent.slice(1);
}).end().slice(-3, -1).remove();
};
let callback = mw.util.debounce(() => {
processLinks(
$('.mw-editfooter-list a, #wikiPreview > .previewnote a'),
{ titlesOnly: true, post }
);
}, 500);
mw.hook('wikipage.editform').add($form => {
callback();
$form.find('.templatesUsed').each(function () {
if (processed.has(this)) return;
processed.add(this);
new MutationObserver(callback)
.observe(this, { childList: true, subtree: true });
});
});
} else if (typeof pageType === 'number') {
$(() => {
processLinks($('.subpages a, .mw-redirectedfrom a, .redirectText a'), {});
});
}
mw.hook('wikipage.content').add($content => {
let titles = new Set();
let $links = $content.find('a');
modules.forEach(module => {
if (module.types && !module.types.includes(pageType)) return;
processLinks($links.filter(module.selector), module, titles);
});
getWatched(titles);
});
}());
mw.hook('listtools.ready').add(extend => {
// extend({
// name: 'talk',
// url: t => !t.isTalkPage() && t.canHaveTalkPage() && t.getTalkPage().getUrl(),
// next: 'hist'
// });
extend({
name: 'subject',
url: t => t.isTalkPage() && t.getSubjectPage().getUrl(),
next: 'hist'
});
extend({
name: 'last',
url: t => !t.missing && t.getUrl({ diff: 'cur', diffonly: 1 }),
next: 'links'
});
// extend({
// name: 'purge',
// url: t => t.getUrl({ action: 'purge' }),
// next: 'watch',
// callback: function (e) {
// e.preventDefault();
// let $link = $(this);
// let $wrapper = $link.parent();
// $link.detach();
// $wrapper.text('purging');
// let pn = $wrapper.closest('.listtools').data('listtools').toText();
// new mw.Api().post({
// action: 'purge',
// forcelinkupdate: 1,
// titles: pn,
// formatversion: 2
// }).then(response => {
// if (response.purge[0].purged) {
// mw.notify(`Purged "${pn}"'`);
// }
// }).always(() => {
// $wrapper.html($link);
// });
// }
// });
extend({
name: 'copy',
url: '#',
callback: function (e) {
e.preventDefault();
let text = $(this).closest('.listtools').data('listtools').toText();
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch (err) {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
}
});
});
(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
mw.config.get('wgCanonicalSpecialPageName') !== 'GlobalContributions' &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector += ', ' + this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i + 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i + 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes += ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i + '/' + count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 + ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 + ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());
if (mw.config.get('wgNamespaceNumber') === 14 && (
mw.config.get('wgAction') === 'view' || !mw.config.get('wgArticleId')
)) {
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox8.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.DateFormatter',
'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget', 'mediawiki.widgets.datetime',
'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-movement',
'mediawiki.interface.helpers.styles', 'user.options'
]);
}
$(function moveHistory() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Move history', 't-movehistory').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.moveHistoryDialog) {
window.moveHistoryDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox5.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'mediawiki.Title', 'mediawiki.DateFormatter',
'oojs-ui-windows', 'oojs-ui-widgets', 'mediawiki.widgets',
'mediawiki.widgets.DateInputWidget', 'oojs-ui.styles.icons-interactions',
'mediawiki.interface.helpers.styles'
]);
});
});
});
$(function sectionSearch() {
if (!document.getElementById('p-tb')) return;
mw.loader.using('mediawiki.util', () => {
let clicked;
mw.util.addPortletLink('p-tb', '#', 'Section search', 't-sectionsearch').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.sectionSearchDialog) {
window.sectionSearchDialog.open();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox7.js&action=raw&ctype=text/javascript');
mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'oojs-ui-core', 'oojs-ui-windows',
'mediawiki.widgets', 'mediawiki.widgets.NamespacesMultiselectWidget'
]);
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'CentralAuth' &&
mw.loader.using('jquery.tablesorter', function sortCentralAuthByEditCount() {
mw.hook('wikipage.content').add($content => {
let $table = $content.find('.mw-centralauth-wikislist').has('td');
if (!$table.length) return;
$table.tablesorter().data('tablesorter').sort([{ 4: 'desc' }, { 1: 'asc' }]);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
[10, 828].includes(mw.config.get('wgNamespaceNumber')) &&
!mw.config.get('wgTitle').endsWith('/doc') &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/AutoTestcases.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/TemplatePreviewGuard.js&action=raw&ctype=text/javascript', 's');
// ['edit', 'submit'].includes(mw.config.get('wgAction')) &&
// $(function templatePreviewGuard() {
// let button = document.querySelector('input[name="wpTemplateSandboxPreview"]');
// if (!button) return;
// let proceed;
// button.addEventListener('click', e => {
// if (proceed) {
// proceed = false;
// return;
// }
// e.preventDefault();
// e.stopPropagation();
// let formData = new FormData(button.form);
// let page = formData.get('wpTemplateSandboxPage');
// let temp = formData.get('wpTemplateSandboxTemplate');
// if (!page || !temp) return;
// mw.loader.using('mediawiki.api').then(() => (
// new mw.Api().get({
// action: 'query',
// titles: page,
// prop: 'templates',
// tltemplates: temp,
// formatversion: 2
// })
// )).always(response => {
// if (((((response || {}).query || {}).pages || [])[0] || {}).templates ||
// confirm(`"${page}" doesn't appear to transclude "${temp}". Continue?`)
// ) {
// proceed = true;
// button.click();
// }
// });
// }, true);
// if (!mw.config.get('wgArticleId')) return;
// let widgetEl = document.querySelector('#wpTemplateSandboxPage.oo-ui-widget');
// if (!widgetEl) return;
// let pn = mw.config.get('wgPageName').replace(/_/g, ' ');
// mw.loader.using(['mediawiki.api', 'oojs-ui-core']).then(() => (
// new mw.Api().get({
// action: 'query',
// titles: pn,
// prop: 'transcludedin',
// tiprop: 'title',
// tilimit: 'max',
// formatversion: 2
// })
// )).then(response => {
// if (!response.batchcomplete) return;
// let pages = response.query.pages[0].transcludedin
// .filter(o => o.title !== pn);
// if (!pages.length) return;
// let widget = OO.ui.infuse(widgetEl);
// if (pages.length === 1) {
// widget.setValue(pages[0].title);
// return;
// }
// widget.$element.replaceWith(
// new OO.ui.ComboBoxInputWidget({
// id: 'wpTemplateSandboxPage',
// maxlength: widget.$input.prop('maxLength'),
// name: widget.$input.prop('name'),
// options: pages
// .sort((a, b) => a.ns - b.ns || -(a.title < b.title))
// .map(o => ({ data: o.title })),
// placeholder: widget.$input.prop('placeholder'),
// tabIndex: widget.getTabIndex(),
// value: widget.getValue()
// }).on('enter', e => {
// e.preventDefault();
// button.click();
// }).$element
// );
// });
// });
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(async () => {
let form = document.getElementById('editform');
if (!form) return;
let formData = new FormData(form);
let section = formData.get('wpSection');
if (section === 'new') return;
let widget = document.getElementById('wpSummaryWidget');
if (!widget) return;
let isOld = formData.get('altBaseRevId') > 0 ||
(formData.get('baseRevId') || formData.get('parentRevId')) !== formData.get('editRevId');
await mw.loader.using([
'jquery.textSelection', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core',
'oojs-ui.styles.icons-editing-core'
]);
let $textarea = $('#wpTextbox1');
let input = OO.ui.infuse(widget);
let button = new OO.ui.ButtonWidget({
framed: false,
icon: 'undo',
classes: ['autosectionlink-button'],
invisibleLabel: true,
label: 'Restore previous section link'
}).toggle().on('click', () => {
let cache = button.getData();
input.setValue(input.getValue().replace(
/^(\/\*.*?\*\/)?\s*/,
cache[0] ? '/* ' + cache[0] + ' */ ' : ''
));
updatePreview(cache[0]);
cache.reverse();
}).on('toggle', () => {
input.$input.css('width', `calc(100% - ${button.$element.width()}px)`);
});
input.$input.after(button.$element);
let update = mw.util.debounce($diff => {
let lines = $textarea.textSelection('getContents').trimEnd().split('\n');
let firstLineNum;
if (isOld) {
let i, lastLineNum;
$diff.find('td:last-child').each(function () {
if (this.classList.contains('diff-lineno')) {
i = this.textContent.replace(/\D+/g, '') - 1;
} else if (this.classList.contains('diff-context')) {
i++;
} else if (this.classList.contains('diff-addedline')) {
i++;
if (!firstLineNum) {
firstLineNum = i;
}
lastLineNum = i;
} else if (this.classList.contains('diff-empty')) {
if (!firstLineNum) {
firstLineNum = i === 0 ? 1 : i;
}
lastLineNum = i;
}
});
lines.length = lastLineNum || 0;
} else {
let origLines = $textarea.prop('defaultValue').trimEnd().split('\n');
firstLineNum = lines.findIndex((line, i) => line !== origLines[i]) + 1;
if (!firstLineNum) {
firstLineNum = lines.length < origLines.length
? lines.length
: 1;
}
for (let i = 1, x = lines.length, y = origLines.length;
(section ? i < x : i <= x) && lines[x - i] === origLines[y - i];
i++
) {
lines.pop();
}
}
let re = /^(={1,6})\s*(.+?)\s*\1\s*(?:<!--.+-->\s*)?$/, lowest = 7;
lines.slice(firstLineNum).forEach(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
lowest = match[1].length;
}
});
let head;
lines.slice(0, firstLineNum).reverse().some(line => {
let match = line.match(re);
if (match?.[1].length < lowest) {
head = match[2];
return true;
}
});
head = head ? head
.replace(/'''(.+?)'''|\[\[:?(?:[^|\]]+\|)?([^\]]+)\]\]|<\/?(?:abbr|b|bdi|bdo|big|cite|code|data|del|dfn|em|font|i|ins|kbd|mark|nowiki|q|rb|ref|rp|rt|rtc|ruby|s|samp|small|span|strike|strong|sub|sup|templatestyles|time|translate|tt|u|var)(?:\s[^>]*)?>|<!--.*?-->|\[(?:https?:)?\/\/[^\s\[\]]+\s([^\]]+)\]/gi, '$1$2$3')
.replace(/''(.+?)''/g, '$1')
.trim() : null;
let match = input.getValue().match(/^(?:\/\*\s*(.*?)\s*\*\/)?\s*(.*?)$/);
let prev = match[1] || '';
if (section < 1 && lowest === 7 && !head) {
head = '';
}
if (prev === head) return;
input.setValue((typeof head === 'string' ? '/* ' + head + ' */ ' : '') + match[2]);
button.setData([prev, head]).toggle(true);
updatePreview(head);
}, 500);
let updatePreview = head => {
let $preview = $('.mw-summary-preview > .comment > span[dir="auto"]');
if (!$preview.length) return;
let hasHead = typeof head === 'string';
let url = hasHead && mw.util.getUrl() + '#' + head.replace(/ /g, '_');
let text = hasHead && (document.dir === 'rtl' ? '←\u200F' : '→\u200E') + (head || mw.messages.get('autocomment-top', '(top)'));
let $ac = $preview.children('.autocomment:first-child');
if ($ac.length && !$ac[0].previousSibling) {
if (hasHead) {
$ac.children('a').attr('href', url).text(text);
} else {
let node = $ac[0].nextSibling;
if (node?.nodeType === 3) {
node.textContent = node.textContent.trimStart();
}
$ac.remove();
}
} else if (hasHead) {
$('<span>').addClass('autocomment').append(
$('<a>').attr({
href: url,
title: mw.config.get('wgPageName').replace(/_/g, ' ')
}).text(text),
mw.messages.get('colon-separator', ': ')
).prependTo($preview);
}
};
if (isOld) {
mw.hook('wikipage.diff').add(update);
} else {
$textarea.on('input', update);
mw.hook('ext.CodeMirror.switch').add((on, $codeMirror) => {
if (on && $codeMirror[0].CodeMirror) {
$codeMirror[0].CodeMirror.on('change', update);
}
});
mw.hook('ext.CodeMirror.input').add(update);
update();
}
new mw.Api().loadMessagesIfMissing(['autocomment-top', 'colon-separator']);
mw.loader.addStyleTag('.autosectionlink-button{position:absolute;top:0;right:0;margin:0}');
});
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(function copyRevId() {
let handler = function (e) {
e.preventDefault();
let text = this.closest('.diff td')?.querySelector('[data-mw-revid]')?.dataset.mwRevid ||
this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!text) return;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
document.execCommand('copy');
$input.remove();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('id')
)
);
});
}());
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
(() => {
let handler = async function (e) {
e.preventDefault();
let td = this.closest('.diff td');
let rev = td
? td.querySelector('[data-mw-revid]')?.dataset.mwRevid
: this.closest('[data-mw-revid]')?.dataset.mwRevid;
if (!rev) {
mw.notify(`Couldn't get the revision.`, {
tag: 'markasunseen',
type: 'error'
});
return;
}
let pn = td
? new URLSearchParams([...td.querySelectorAll('a')].pop()?.search).get('title')
: mw.config.get('wgPageName');
if (!pn) return;
await mw.loader.using('mediawiki.api');
let result = (await new mw.Api().postWithEditToken({
action: 'setnotificationtimestamp',
[td ? 'newerthanrevid' : 'torevid']: rev,
titles: pn,
formatversion: 2
})).setnotificationtimestamp?.[0];
if (Object.hasOwn(result, 'notificationtimestamp')) {
mw.notify(`Marked revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'success'
});
} else if (result?.notwatched) {
mw.notify('This page is not on your watchlist.', {
tag: 'markasunseen',
type: 'warn'
});
} else {
mw.notify(`Couldn't mark revisions ${td ? 'after' : 'since'} ${rev} as unseen.`, {
tag: 'markasunseen',
type: 'error'
});
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1').append(
' (',
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions after this one as unseen'
}).on('click', handler).text('unseen'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button',
title: 'Mark revisions since this one as unseen'
}).on('click', handler).text('unseen')
)
);
});
})();
(mw.config.get('wgNamespaceNumber') === -1 || mw.config.exists('wgDiffNewId') ||
mw.config.get('wgAction') === 'history') &&
((mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4) ||
(mw.config.get('wgWikiID') === 'metawiki' && mw.config.get('wgPageContentModel') === 'wikitext')) &&
mw.loader.using(['mediawiki.util', 'mediawiki.Title'], function copyUnsig() {
let handler = function (e) {
e.preventDefault();
let parent = this.closest('li, td');
let ts = parent.textContent.match(/\d\d:\d\d, \d\d? [A-Z][a-z]+ \d{4}/)?.[0];
if (!ts) return;
let user = parent.querySelector('.mw-userlink').textContent;
if (mw.util.isIPv6Address(user)) {
user = user.toUpperCase();
}
let temp = mw.util.isIPAddress(user) ? 'unsigned IP' : 'unsigned';
let text = `{{subst:${temp}|${user}|${ts}}}`;
let $input = $('<input>').attr({
type: 'text',
readonly: '',
style: 'position:fixed;top:-100%'
}).val(text).appendTo(document.body);
$input[0].select();
let copied;
try {
copied = document.execCommand('copy');
} catch {}
$input.remove();
if (copied) {
mw.notify(`Copied "${text}"`);
} else {
mw.notify('Copy failed', { type: 'error' });
}
};
mw.hook('wikipage.diff').add($diff => {
$diff.find('#mw-diff-otitle1, #mw-diff-ntitle1').filter(function () {
if (mw.config.get('wgWikiID') === 'metawiki') {
return true;
}
let link = this.querySelector('strong > a') ||
this.parentElement.querySelector('#differences-prevlink, #differences-nextlink');
if (!link) return;
let t = mw.Title.newFromText(mw.util.getParamValue('title', link.search));
return t.isTalkPage() || t.namespace === 4;
}).append(
' (',
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig'),
')'
);
});
if (mw.config.get('wgAction') !== 'history') return;
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-tools').append(
$('<span>').append(
$('<a>').attr({
href: '#',
role: 'button'
}).on('click', handler).text('sig')
)
);
});
});
// mw.config.get('wgAction') === 'history' &&
// mw.loader.using('mediawiki.util', function () {
// mw.hook('wikipage.content').add($content => {
// $content.find('a.mw-changeslist-date').after(function () {
// return [
// ' (',
// $('<a>').attr('href', mw.util.getUrl(null, {
// action: 'edit',
// oldid: this.closest('li').dataset.mwRevid
// })).text('e'),
// ')'
// ];
// });
// });
// });
// ['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
// mw.hook('wikipage.content').add($content => {
// $content.find('.mw-changeslist-history').parent().after(function () {
// return $('<span>').append(
// $('<a>').attr(
// 'href',
// this.firstElementChild.getAttribute('href').slice(0, -7) + 'edit'
// ).text('e')
// );
// });
// });
if (screen.width < 500) {
mw.loader.addStyleTag('@font-face{font-family:CharisW;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/017b2b2ad86e09d3c22b8cf0dfc78247/CharisSILRegular.ttf) format(truetype)} @font-face{font-family:CharisW;font-weight:700;src:url(//fontlibrary.org/assets/fonts/charis/10b9f94ed21e56254b068c91ead7ec6f/6f5069ac6a300dad45383c952e92c573/CharisSILBold.ttf) format(truetype)} body .IPA{font-family:CharisW,sans-serif} .mw-highlight-lines > pre{width:120em}');
location.hash && $(() => {
let target = document.querySelector(':target');
if (target?.getBoundingClientRect().top < 0) {
target.scrollIntoView();
}
});
}
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
(mw.config.exists('wgCodeEditorCurrentLanguage') ||
mw.config.exists('cmMode') && mw.config.get('cmMode') !== 'mediawiki') &&
(function saveNEdit() {
let notif;
$(document.body).on('click', '#wpSave', async function (e) {
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey ||
e.originalEvent?.defaultPrevented
) {
return;
}
e.preventDefault();
await mw.loader.using([
'mediawiki.api', 'mediawiki.util', 'jquery.textSelection', 'oojs-ui-core'
]);
let button = OO.ui.infuse(this.parentElement).setDisabled(true);
let $textarea = $('#wpTextbox1');
let text = $textarea.textSelection('getContents');
let $summary = $('#wpSummary');
let formData = new FormData(this.form);
let promise = new mw.Api().postWithEditToken({
action: 'edit',
title: mw.config.get('wgPageName'),
text: text,
section: formData.get('wpSection') || undefined,
summary: $summary.textSelection('getContents'),
[$('#wpMinoredit').prop('checked') ? 'minor' : 'notminor']: 1,
baserevid: formData.get('editRevId'),
basetimestamp: formData.get('wpEdittime'),
starttimestamp: formData.get('wpStarttime'),
watchlist: $('#wpWatchthis').prop('checked') ? 'watch' : 'unwatch',
watchlistexpiry: formData.get('wpWatchlistExpiry') || undefined,
undo: formData.get('wpUndidRevision') || undefined,
undoafter: formData.get('wpUndoAfter') || undefined,
contentformat: formData.get('format'),
contentmodel: formData.get('model'),
assertuser: mw.config.get('wgUserName'),
formatversion: 2
});
notif?.close();
notif = null;
try {
let response = await promise;
if (response?.edit?.result !== 'Success') throw '';
$('#editform > input[name="wpUndidRevision"], #editform > input[name="wpUndoAfter"]').remove();
$textarea.data('origtext', text).prop('defaultValue', text);
$summary.val($summary.prop('defaultValue'));
if (mw.loader.getState('mediawiki.editRecovery.edit') === 'ready') {
let storage = mw.loader.moduleRegistry['mediawiki.editRecovery.edit'].packageExports['storage.js'];
storage.deleteData(mw.config.get('wgPageName'));
storage.closeDatabase();
}
notif = await mw.notify(response.edit.nochange ? 'No change' : [
document.createTextNode('Saved'),
$('<p>').append(
new OO.ui.ButtonWidget({
href: mw.util.getUrl(),
target: '_blank',
label: 'View'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, {
diff: response.edit.newrevid || 'cur',
diffonly: 1
}),
target: '_blank',
label: 'Diff'
}).$element,
new OO.ui.ButtonWidget({
href: mw.util.getUrl(null, { action: 'history' }),
target: '_blank',
label: 'History'
}).$element
)[0]
], { tag: 'savenedit' });
} catch (error) {
notif = await mw.notify(error?.error?.info || error || 'Save failed', {
autoHideSeconds: 'long',
tag: 'savenedit',
type: 'error'
});
} finally {
button.setDisabled();
}
});
}());
mw.config.get('wgNamespaceNumber') === 0 &&
mw.config.get('wgAction') === 'view' &&
mw.config.get('wgCategories')?.some(c => c.endsWith(' actors') || c.endsWith(' actresses')) &&
$(() => {
let n = $.escapeSelector(mw.config.get('wgTitle').replace(/ \(.+\)$/, ''));
let $links = $(`.hatnote a[title$="${n} filmography"], .hatnote a[title*="${n} on "], .hatnote a[title*="${n} performances"]`);
if (!$links.length) return;
let titles = {};
$links = $links.filter(function () {
let text = this.textContent;
return !(titles[text] = Object.hasOwn(titles, text));
});
mw.notify(
$links.length === 1
? $links.clone()
: $('<ul>').append($links.clone().wrap('<li>').parent()),
{ autoHideSeconds: 'long' }
);
});
['Recentchanges', 'Recentchangeslinked', 'Watchlist'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
$.when($.ready, mw.loader.using([
'user.options', 'mediawiki.util', 'mediawiki.api'
])).then(function rcMuter() {
let os = mw.user.options.get('userjs-rcmuter');
let set = new Set(os && os.split('|'));
let save = () => {
let ns = [...set].join('|');
if (ns === mw.user.options.get('userjs-rcmuter')) return;
new mw.Api().saveOption('userjs-rcmuter', ns);
mw.user.options.set('userjs-rcmuter', ns);
$edit.attr('data-rcmuter', set.size);
};
mw.loader.addStyleTag('body:not(.rcmuter-disabled) .rcmuter-muted{display:none !important} .rcmuter-edit::after, .rcmuter-togglemuted::after{content:": " attr(data-rcmuter)}');
let $edit = $('<a>').attr({
class: 'rcmuter-edit',
href: '#',
'data-rcmuter': set.size
}).text('Edit muted').on('click', e => {
e.preventDefault();
mw.loader.using([
'oojs-ui-windows', 'mediawiki.widgets.UsersMultiselectWidget'
]).then(() => OO.ui.getWindowManager().getWindow('message')).then(dialog => {
let multiselect = new mw.widgets.UsersMultiselectWidget({
$overlay: dialog.$overlay,
ipAllowed: true,
selected: [...set]
}).connect(dialog, { change: 'updateSize', reorder: 'updateSize' });
let instance = dialog.open({
message: $([
document.createTextNode('Muted users:'),
multiselect.$element[0]
]),
size: 'medium'
});
instance.opened.then(() => {
setTimeout(() => {
multiselect.focus().menu.toggle(false);
});
});
instance.closed.then(result => {
if (!result || result.action !== 'accept') return;
set = new Set(multiselect.getSelectedUsernames());
save();
mw.notify('Changes will take effect in next load.', {
tag: 'rcmuter'
});
});
});
});
let buttonsShown;
let $toggleButtons = $('<a>').attr('href', '#').text('Show toggle buttons').on('click', function (e) {
e.preventDefault();
if (buttonsShown) {
mw.hook('wikipage.content').remove(addButtons);
$('.rcmuter-toggle').remove();
this.textContent = 'Show toggle buttons';
} else {
mw.hook('wikipage.content').add(addButtons);
this.textContent = 'Hide toggle buttons';
}
buttonsShown = !buttonsShown;
});
let $toggle = $('<a>').attr({
class: 'rcmuter-togglemuted',
href: '#'
}).text('Show muted').on('click', function (e) {
e.preventDefault();
this.textContent = document.body.classList.toggle('rcmuter-disabled')
? 'Hide muted'
: 'Show muted';
});
let $toggleSpan = $('<span>').hide().append($toggle);
mw.util.addSubtitle(
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append($edit),
$('<span>').append($toggleButtons),
$toggleSpan
)[0]
);
let toggle = function (e) {
e.preventDefault();
let user = $(this)
.closest('.mw-userlink ~ .mw-usertoollinks, .mw-changeslist-line-inner-userLink ~ .mw-changeslist-line-inner-userTalkLink')
.prevAll('.mw-userlink, .mw-changeslist-line-inner-userLink')
.last().text().trim();
if (!user) {
mw.notify(`Can't retrieve the username.`, {
tag: 'rcmuter',
type: 'error'
});
return;
}
let muting = this.parentElement.classList.toggle('rcmuter-unmute');
set[muting ? 'add' : 'delete'](user);
save();
this.textContent = muting ? 'unmute' : 'mute';
mw.notify(`${muting ? 'Muting' : 'Unmuting'} ${user} from next load.`, {
tag: 'rcmuter'
});
};
let addButtons = $content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) {
$content = $('#mw-content-text');
if ($content.has('.rcmuter-toggle').length) return;
}
let $tools = $content.find('.mw-usertoollinks.mw-changeslist-links');
let $muted = $tools.filter('.rcmuter-muted *');
$tools.not($muted).append(
$('<span>').addClass('rcmuter-toggle').append(
$('<a>').attr('href', '#').text('mute').on('click', toggle)
)
);
if (!$muted.length) return;
$muted.append(
$('<span>').addClass('rcmuter-toggle rcmuter-unmute').append(
$('<a>').attr('href', '#').text('unmute').on('click', toggle)
)
);
};
let mutedCount;
let filter = function () {
let muted = set.has(this.textContent);
if (muted) mutedCount++;
return muted;
};
mw.hook('wikipage.content').add($content => {
if (!$content.is('#mw-content-text, .mw-changeslist')) return;
if (!set.size) {
$toggleSpan.hide();
return;
}
mutedCount = 0;
$content.find('.changedby > .mw-userlink:only-child')
.filter(filter).closest('table').addClass('rcmuter-muted');
$content.find('.mw-userlink:not(.changedby > *, .comment *, .rcmuter-muted *)')
.filter(filter).closest('.mw-changeslist-line, table').addClass('rcmuter-muted')
.closest('table.mw-enhanced-rc').find('.changedby > .mw-userlink').filter(filter).addClass('rcmuter-muted');
$toggleSpan.toggle(!!mutedCount);
$toggle.attr('data-rcmuter', mutedCount);
});
});
location.hostname.endsWith('.wikipedia.org') &&
mw.config.get('wgNamespaceNumber') % 2 === 0 &&
// mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.util')).then(function refRenamer() {
if (!document.getElementById('p-tb')) return;
let messages = Object.assign({
portlet: 'RefRenamer',
loading: 'Loading RefRenamer...'
}, window.refrenamerMessages);
let clicked;
mw.util.addPortletLink('p-tb', '#', messages.portlet, 't-refrenamer').firstElementChild.addEventListener('click', e => {
e.preventDefault();
if (clicked) {
if (window.refRenamer) {
window.refRenamer();
}
return;
}
clicked = true;
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox6.js&action=raw&ctype=text/javascript');
mw.notify(messages.loading, {
autoHideSeconds: 'long',
tag: 'refrenamer'
});
});
});
if (['edit', 'submit'].includes(mw.config.get('wgAction'))) {
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/ExpandContractions.js&action=raw&ctype=text/javascript', 's');
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/Unpipe.js&action=raw&ctype=text/javascript', 's');
}
mw.config.get('wgAction') !== 'history' &&
mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Nardog/CopyCodeBlock.js&action=raw&ctype=text/javascript', 's');
mw.config.exists('wgDiffNewId') &&
mw.config.get('wgDiscussionToolsFeaturesEnabled') &&
(function () {
let data = {}, clickHandler, autoClear, run;
window.dtc = data;
let highlight = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
mw.loader.moduleRegistry['ext.discussionTools.init'].packageExports['highlighter.js']
.highlightNewComments(mw.dt.pageThreads, true, ids);
if (clickHandler) {
$(document.body).off('click', clickHandler);
return;
}
$._data(document.body, 'events').click.some(o => {
if (String(o.handler).includes('highlighter.clearHighlightTargetComment(')) {
$(document.body).off('click', o.handler);
clickHandler = o.handler;
return true;
}
});
$._data(window, 'events').popstate.some(o => {
if (String(o.handler).includes('highlighter.highlightTargetComment(')) {
$(window).off('popstate', o.handler);
return true;
}
});
};
let scroll = revId => {
let ids = data[revId];
if (!ids || !ids.length) return;
let yToSpan = Object.fromEntries(
ids.map(id => document.getElementById(id)).filter(Boolean)
.map(span => [span.getBoundingClientRect().y, span])
);
let ys = Object.keys(yToSpan);
if (!ys.length) return;
let lower = ys.filter(y => y > 10);
if (!lower.length ||
Math.max(...lower) < document.documentElement.clientHeight
) {
yToSpan[Math.min(...ys)].scrollIntoView();
} else {
yToSpan[Math.min(...lower)].scrollIntoView();
}
};
let scrollToNext = function (e) {
e.preventDefault();
let revId = mw.config.get('wgDiffOldId');
if (!revId || !data[revId]) return;
let i = data[revId].indexOf(
this.closest('[data-mw-thread-id]').dataset.mwThreadId
);
if (i === -1) return;
let next = data[revId][i + 1] || data[revId][0];
document.getElementById(next).scrollIntoView();
};
mw.hook('wikipage.content').add(async $content => {
let revId = mw.config.get('wgDiffOldId');
if (!revId) return;
let param = new URLSearchParams(location.search).get('diffonly');
if (param && param !== '0') return;
if (data[revId]) {
highlight(revId);
return;
}
await mw.loader.using(['ext.discussionTools.init', 'mediawiki.util']);
let begin = Date.parse($('#mw-diff-otitle1 .mw-diff-timestamp').data('timestamp'));
data[revId] = mw.dt.pageThreads.getCommentItems()
.filter(c => c.timestamp > begin).map(c => c.id);
if (!data[revId].length) return;
await new Promise(setTimeout);
highlight(revId);
$content.find('.ext-discussiontools-init-replylink-buttons').filter(function () {
return data[revId].includes(this.dataset.mwThreadId);
}).children('span:last-of-type').before(
' | ',
$('<a>').attr({
href: '#',
role: 'button'
}).text('next').on('click', scrollToNext)
);
if (run || !document.getElementById('p-tb')) return;
run = true;
let portlet = mw.util.addPortletLink('p-tb', '#', 'Scroll to next', 't-scrolltonext');
portlet.firstElementChild.addEventListener('click', e => {
e.preventDefault();
scroll(mw.config.get('wgDiffOldId'));
});
mw.util.addPortletLink('p-tb', '#', 'Toggle highlight', 't-togglehighlight').firstElementChild.addEventListener('click', e => {
e.preventDefault();
autoClear = !autoClear;
if (autoClear) {
$(document.body).on('click', clickHandler)[0].click();
} else {
highlight(mw.config.get('wgDiffOldId'));
}
});
mw.loader.addStyleTag(`#t-scrolltonext{position:fixed;bottom:${portlet.clientHeight}px} #t-togglehighlight{position:fixed;bottom:0}`);
});
}());
mw.config.get('wgNamespaceNumber') === 6 &&
mw.config.get('wgAction') === 'view' &&
mw.hook('wikipage.content').add($content => {
$content.find('.filehistory .mw-usertoollinks-contribs').after(function () {
return [
' | ',
$('<a>').attr('href', `${
mw.config.get('wgScript')
}?title=Special:ListFiles/${
this.pathname.replace(/^.+\//, '')
}&ilshowall=1`).text('uploads')
];
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$(function () {
if (!$('input[name="wpSection"]').val()) return;
mw.hook('wikipage.content').add(async $content => {
let $refs = $content.find('.mw-ext-cite-warning-sectionpreview_no_text');
if (!$refs.length) return;
let ids = {};
$refs.each(function () {
ids[this.closest('[id]').id.replace(/-\d+$/, '')] = this;
});
let response = await $.get(`/api/rest_v1/page/html/${encodeURIComponent(mw.config.get('wgPageName'))}`);
$($.parseHTML(response)).find('.mw-reference-text').each(function () {
ids[this.id.replace(/^mw-reference-text-|-\d+$/g, '')]?.replaceWith(this);
});
});
});
mw.hook('moremenu.ready').add(config => {
$('#mm-page-purge-cache > a').on('click', e => {
e.preventDefault();
new mw.Api().post({
action: 'purge',
forcelinkupdate: 1,
titles: config.page.name,
formatversion: 2
}).then(() => {
location.href = mw.util.getUrl();
});
});
$('#mm-page-search-search-history-wikiblame > a').on('click', function (e) {
e.preventDefault();
let q = prompt();
if (q === null) return;
let href = this.href;
if (q) {
let removal = q[0] === '!';
if (removal) {
q = q.slice(1);
}
href += '&needle=' + encodeURIComponent(q);
if (removal) {
href += '&binary_search_inverse=on';
}
href += '&force_wikitags=on';
}
open(href, '_blank');
});
$('#mm-page-expand-templates > a').on('click auxclick', function (e) {
if (e.which > 2) return;
e.preventDefault();
let revId = mw.config.get('wgRevisionId') || Number($('input[name=oldid]').val());
let url = revId
? '/w/rest.php/v1/revision/' + revId
: '/w/rest.php/v1/page/' + config.page.encodedName;
$.get(url).then(response => {
$('<form>').attr({
method: 'post',
action: this.href,
target: '_blank'
}).append(
[
['wpInput', response.source],
['wpContextTitle', config.page.name],
['wpRemoveComments', 1]
].map(([n, v]) => $('<input>').attr({
name: n,
type: 'hidden'
}).val(v))
).appendTo(document.body).trigger('submit').remove();
});
});
});
mw.config.get('wgCanonicalSpecialPageName') === 'ApiSandbox' &&
mw.hook('apisandbox.formatRequest').add((...args) => {
args[4].complete = function () {
setTimeout(() => {
mw.hook('wikipage.content').fire($('.oo-ui-pageLayout-active'));
}, 100);
};
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.config.get('wgArticleId') &&
mw.config.get('wgPageContentModel') === 'wikitext' &&
$.when($.ready, mw.loader.using('mediawiki.storage')).then(async () => {
let infuseAndCall = (query, method, ...args) => {
let $widget = $(query);
if ($widget.length) {
return OO.ui.infuse($widget)[method](...args);
}
};
let section = $('input[name="wpSection"]').val();
if (section) {
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let save = () => {
let newSource = $textarea.textSelection('getContents');
if (newSource === source) {
mw.storage.session.remove('editfullpage');
} else {
mw.storage.session.setObject('editfullpage', [
mw.config.get('wgPageName'),
section,
newSource.trimEnd(),
infuseAndCall('#wpSummaryWidget', 'getValue') || '',
Number(infuseAndCall('#wpMinoreditWidget', 'isSelected')) || 0,
Number(infuseAndCall('#wpWatchthisWidget', 'isSelected')) || 0,
infuseAndCall('#wpWatchlistExpiryWidget', 'getValue') || 'infinite'
]);
}
};
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
setInterval(() => {
mw.requestIdleCallback(save);
}, 3000);
window.addEventListener('beforeunload', save);
return;
}
let data = mw.storage.session.getObject('editfullpage');
mw.storage.session.remove('editfullpage');
console.log(data);
if (!data || data[0] !== mw.config.get('wgPageName')) return;
let isNew = data[1] === 'new';
let isLead = data[1] === '0';
let $textarea = $('#wpTextbox1');
let source = $textarea.prop('defaultValue');
let newSource, start, msg, notifOpts = { autoHideSeconds: 'long' };
let orig = [];
if (isNew) {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core']);
newSource = source + (data[3] ? '\n== ' + data[3] + ' ==\n\n' : '\n') + data[2] + '\n';
start = source.length;
} else {
await mw.loader.using(['jquery.textSelection', 'oojs-ui-core', 'mediawiki.api']);
let { parse } = await new mw.Api().get({
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
wrapoutputclass: '',
disablelimitreport: 1,
disableeditsection: 1,
disabletoc: 1,
formatversion: 2
});
let target = !isLead && parse.sections.find(s => s.index === data[1]);
if (isLead || target) {
let next = parse.sections.find(s => s.index - 1 === Number(data[1]));
newSource = (isLead ? '' : [...source].slice(0, target.byteoffset)).join('') +
data[2] + (next ? '\n\n' + [...source].slice(next.byteoffset).join('') : '\n');
start = isLead ? 0 : target.byteoffset;
} else {
newSource = source + '\n\n' + data[2] + '\n';
start = source.length;
msg = `Section restored. Couldn't find the section. The source is appended at bottom.`;
notifOpts.type = 'warn';
}
orig[0] = infuseAndCall('#wpSummaryWidget', 'getValue');
infuseAndCall('#wpSummaryWidget', 'setValue', data[3]);
}
$textarea.textSelection('setContents', newSource);
orig[1] = infuseAndCall('#wpMinoreditWidget', 'getSelected');
infuseAndCall('#wpMinoreditWidget', 'setSelected', data[4]);
orig[2] = infuseAndCall('#wpWatchthisWidget', 'getSelected');
infuseAndCall('#wpWatchthisWidget', 'setSelected', data[5]);
orig[3] = infuseAndCall('#wpWatchlistExpiryWidget', 'getValue');
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', data[6]);
setTimeout(() => {
$textarea.textSelection('setSelection', { start });
});
let notif = await mw.notify($([
document.createTextNode(msg || 'Section restored.'),
$('<p>').append(
new OO.ui.ButtonWidget({
flags: 'destructive',
label: 'Discard'
}).on('click', () => {
$textarea.textSelection('setContents', source);
if (orig[0]) {
infuseAndCall('#wpSummaryWidget', 'setValue', orig[0]);
}
infuseAndCall('#wpMinoreditWidget', 'setSelected', orig[1]);
infuseAndCall('#wpWatchthisWidget', 'setSelected', orig[2]);
infuseAndCall('#wpWatchlistExpiryWidget', 'setValue', orig[3]);
notif.close();
}).$element
)[0]
]), notifOpts);
});
mw.config.exists('wgPostEdit') &&
mw.loader.using('mediawiki.storage', () => {
mw.storage.session.remove('editfullpage');
});
mw.config.get('wgAction') === 'history' &&
mw.hook('wikipage.content').add(async $content => {
if (!$content.has('.mw-history-line-updated').length) return;
let href = $content.find('a.mw-history-histlinks-current:not(.mw-history-line-updated a)').attr('href');
if (!href) {
await mw.loader.using(['mediawiki.api', 'mediawiki.util']);
let page = (await new mw.Api().get({
action: 'query',
titles: mw.config.get('wgPageName'),
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev >= page.lastrevid) return;
href = mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
}
$content.find('.mw-history-compareselectedversions-button').first().after(
' ',
$('<a>').attr({
class: 'unseendiff',
href: href
}).text('unseen')
);
});
(async () => {
let cspn = mw.config.get('wgCanonicalSpecialPageName');
let isBp = cspn === 'Blankpage';
if (!isBp && cspn !== 'Watchlist') return;
await mw.loader.using('mediawiki.util');
let notify = async (text, options, pn) => {
let msg = [document.createTextNode(text)];
if (pn) {
msg.push(
$('<p>').append(
$('<a>').attr('href', mw.util.getUrl(pn)).text(pn),
' ',
$('<span>').addClass('mw-changeslist-links').append(
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'edit' }))
.text('edit')
),
$('<span>').append(
$('<a>')
.attr('href', mw.util.getUrl(pn, { action: 'history' }))
.text('history')
)
)
)[0]
);
}
if (isBp) {
await $.ready;
$('#mw-content-text').html(msg);
} else {
return mw.notify(msg, Object.assign(options || {}, {
tag: 'unseendiff'
}));
}
};
let getUrl = async pn => {
await mw.loader.using('mediawiki.api');
let page = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'info',
inprop: 'notificationtimestamp',
formatversion: 2
})).query.pages[0];
if (!page.notificationtimestamp) {
notify(`Couldn't get the last seen time.`, {
type: 'warn'
}, pn);
return;
}
let rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (rev === page.lastrevid) {
notify('Already seen.', {
type: 'warn'
}, pn);
return;
}
if (!rev) {
rev = (await new mw.Api().get({
action: 'query',
titles: pn,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
rvdir: 'newer',
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev) {
notify(`Couldn't get the last seen revision.`, {
type: 'warn'
}, pn);
return;
}
}
if (rev > page.lastrevid) {
notify(`Invalid rev for "${pn}" (rev: ${rev}, lastrevid: ${page.lastrevid})`, {
autoHideSeconds: 'long',
type: 'warn'
}, pn);
return;
}
return mw.util.getUrl(page.title, { diff: page.lastrevid, oldid: rev });
};
if (isBp) {
let pn = mw.config.get('wgTitle').match(/^[^/]+\/unseendiff\/(.+)$/)?.[1];
if (!pn) return;
notify('Loading...', null, pn);
let href = await getUrl(pn);
if (!href) return;
notify('Redirecting...', null, pn);
location.href = href;
return;
}
let handler = async function (e) {
if (e.which > 2) return;
e.preventDefault();
let pn = this.dataset.pn;
if (!pn) {
notify(`Couldn't get the page name.`, {
type: 'error'
});
return;
}
let notifPromise = notify('Loading...', {
autoHideSeconds: 'long'
});
let href = await getUrl(pn);
if (!href) return;
$(`.unseendiff-loader[data-pn="${$.escapeSelector(pn)}"]`).attr({
class: 'unseendiff',
href: href,
target: '_blank'
}).off('click auxclick', handler);
if (e.type === 'auxclick' || e.ctrlKey || e.metaKey || e.shiftKey) {
open(href);
} else {
this.click();
}
(await notifPromise).close();
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-changeslist-src-mw-edit.mw-changeslist-watchedunseen:not(.mw-changeslist-watchedseen) .mw-changeslist-line-inner'
).each(function () {
let pn = this.dataset.targetPage ||
this.closest('[data-target-page]')?.dataset.targetPage ||
this.closest('table.mw-enhanced-rc')?.querySelector('[data-target-page]')?.dataset.targetPage;
if (!pn) return;
$('<span>').append(
$('<a>').attr({
class: 'unseendiff-loader',
href: mw.util.getUrl(`Special:BlankPage/unseendiff/${pn}`),
'data-pn': pn
}).on('click auxclick', handler).text('unseen')
).appendTo(
[...this.querySelectorAll('.mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
});
})();
['Contributions', 'IPContributions', 'Blankpage'].includes(mw.config.get('wgCanonicalSpecialPageName')) &&
mw.loader.using('mediawiki.util', () => {
let watched = new Set();
let query = async lis => {
let titles = Object.keys(lis).slice(0, 50);
if (!titles.length) return;
await mw.loader.using('mediawiki.api');
let pages = (await new mw.Api().post({
action: 'query',
titles: titles,
prop: 'info',
inprop: 'notificationtimestamp|watched',
formatversion: 2
}, {
headers: { 'Promise-Non-Write-API-Action': 1 }
})).query.pages;
for (let page of pages) {
if (!Object.hasOwn(lis, page.title)) continue;
if (page.watched) {
watched.add(page);
$(lis[page.title]).addClass('watched');
}
if (!page.notificationtimestamp) continue;
let rev = (await new mw.Api().get({
action: 'query',
titles: page.title,
prop: 'revisions',
rvprop: 'ids',
rvlimit: 1,
rvstart: Date.parse(page.notificationtimestamp) / 1000 - 1,
formatversion: 2
})).query.pages[0].revisions?.[0].revid;
if (!rev || rev === page.lastrevid) continue;
if (rev > page.lastrevid) {
mw.notify($([
document.createTextNode('Invalid rev for "'),
$('<a>').attr({
href: mw.util.getUrl(page.title, { action: 'history' }),
target: '_blank'
}).text(page.title)[0],
document.createTextNode(`" (rev: ${rev}, lastrevid: ${page.lastrevid})`),
]), {
autoHideSeconds: 'long',
type: 'warn'
});
continue;
}
$('<span>').append(
$('<a>').attr({
class: 'unseendiff',
href: mw.util.getUrl(page.title, {
diff: page.lastrevid,
oldid: rev
})
}).text('unseen')
).appendTo(
lis[page.title].map(li => (
[...li.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(li).before(' ')
))
);
}
titles.forEach(title => {
delete lis[title];
});
query(lis);
};
mw.hook('wikipage.content').add($content => {
$content.find(
'.mw-contributions-list > li:not(.mw-contributions-current)[data-mw-revid]'
).each(function () {
let link = this.querySelector('a.mw-changeslist-date, a.mw-changeslist-history');
let pn = link ? new URLSearchParams(link.search).get('title') : '';
$('<span>').append(
$('<a>').attr({
class: 'mw-changeslist-diff',
href: mw.util.getUrl(pn, {
diff: 'cur',
oldid: this.dataset.mwRevid
})
}).text('cur')
).appendTo(
[...this.querySelectorAll(':scope > .mw-pager-tools')].pop() ||
$('<span>').addClass('mw-changeslist-links mw-pager-tools').appendTo(this).before(' ')
);
});
if (mw.config.get('wgWikiID') === 'wikidatawiki') return;
let lis = {};
$content.find('.mw-contributions-title').each(function () {
let title = this.textContent;
if (!Object.hasOwn(lis, title)) {
lis[title] = [];
}
lis[title].push(this.closest('li'));
});
Object.keys(lis).forEach(title => {
if (watched.has(title)) {
$(lis[title]).addClass('watched');
delete lis[title];
}
});
query(lis);
});
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
mw.loader.load('//test.wikipedia.org/w/index.php?title=User:Nardog/sandbox9.js&action=raw&ctype=text/javascript');
mw.config.get('wgWikiID') === 'metawiki' &&
(async () => {
let css = mw.loader.addStyleTag(`.wishtitle {
font-size: 90%;
font-style: italic;
word-break: break-word;
}
.wishtitle > a {
color: var(--color-warning, #886425);
}
.wishtitle > a:visited {
color: var(--border-color-warning--hover, #735421);
}
.wishtitle-declined > a {
text-decoration: line-through;
}
.wishtitle-declined > a:hover,
.wishtitle-declined > a:focus,
.mw-underline-always .wishtitle-declined > a {
text-decoration: line-through underline;
}
#watchlist-edit-form .wishtitle {
display: inline-block;
}
.mw-search-result-heading > .wishtitle,
.catchangesviewer-table .wishtitle {
display: block;
}
.catchangesviewer-table:has(.wishtitle) {
white-space: wrap;
}`);
let lang = mw.config.get('wgUserLanguage');
let titles;
let loadTitles = async () => {
await mw.loader.using('mediawiki.storage');
titles = titles || mw.storage.getObject('wishtitles');
if (titles?.lang !== lang) {
titles = { lang, w: [], fa: [] };
}
};
let updateTitles = async (crwstatuses, crwcontinue) => {
await mw.loader.using('mediawiki.api');
let params = {
action: 'query',
list: 'communityrequests-wishes',
crwlang: lang,
crwstatuses: crwstatuses,
crwprop: 'title|updated',
crwsort: 'updated',
crwdir: 'ascending',
crwlimit: 'max',
crwcontinue: crwcontinue,
formatversion: 2
};
if (!crwcontinue && !crwstatuses && titles._) {
params.crwcontinue = `|${titles._}|0`;
}
let response = await new mw.Api().get(params);
let wishes = response?.query?.['communityrequests-wishes'];
if (wishes?.length) {
let $span = $('<span>');
wishes.forEach(w => {
let id = w.crwtitle.match(/^Community Wishlist\/W(\d+)/)?.[1];
if (!id) return;
titles.w[id - 1] = $span.html(w.title).text();
if (crwstatuses === 'declined') {
(titles.wd = titles.wd || []).push(id - 1);
}
let faId = w.crfatitle?.match(/^Community Wishlist\/FA(\d+)/)?.[1];
if (!faId) return;
titles.fa[faId - 1] = w.focusareatitle;
});
if (!crwstatuses) {
titles._ = wishes.at(-1).updated.replace(/\D/g, '');
}
}
let expiry = 86400;
if (crwstatuses || crwcontinue) {
let prev = mw.storage.getObject('_EXPIRY_wishtitles');
if (prev) {
expiry = Math.round(Date.now() / 1000) + 86400 - prev;
}
}
mw.storage.setObject('wishtitles', titles, expiry);
crwcontinue = response?.continue?.crwcontinue;
if (crwcontinue) {
await updateTitles(crwstatuses, crwcontinue);
}
};
let getTitle = id => (
id[0] === 'W' ? titles.w[id.slice(1) - 1] : titles.fa[id.slice(2) - 1]
);
let renderTitle = (title, id, tag = 'span') => {
let classes = 'wishtitle';
if (id[0] === 'W' && titles.wd?.includes(id.slice(1) - 1)) {
classes += ' wishtitle-declined';
}
return $(`<${tag}>`).addClass(classes).append(
$('<a>').attr({
href: `/wiki/Community_Wishlist/${id}`,
title: `Community Wishlist/${id}`
}).text(title)
);
};
let callback = ([id, links]) => {
let title = getTitle(id);
if (!title) {
return true;
}
$(links).after(' ', renderTitle(title, id));
};
let selector = '.mw-changeslist-title, ' +
'.mw-changeslist-log-entry > a:not(.mw-userlink), ' +
'.mw-changeslist-line.mw-changeslist-src-mw-categorize :is(.mw-changeslist-line-inner, .mw-changeslist-line-inner-comment, .mw-enhanced-rc-nested) > .comment > a, ' +
'#watchlist-edit-form .cdx-table td > label > a, ' +
'.mw-search-result-heading > a:not(:has(> .ext-communityrequests-entity-link--label)), ' +
'.mw-contributions-title, ' +
'#mw-whatlinkshere-list li > bdi > a, ' +
'.mw-allpages-chunk > li > a, ' +
'.mw-prefixindex-list > li > a, ' +
'.mw-logevent-loglines > li > a, ' +
'#mw-pages li > a, ' +
'.catchangesviewer-table td:nth-child(3) > a';
mw.hook('wikipage.content').add(async $content => {
let links = {};
$content.find('a').each(function () {
if (!this.matches(selector)) return;
let id = this.textContent.match(
/^(?:Talk:|Translations:)?Community Wishlist\/((?:W|FA)\d+)/
)?.[1];
if (!id) return;
(links[id] = links[id] || []).push(this);
});
links = Object.entries(links);
if (!links.length) return;
await loadTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles();
links = links.filter(callback);
if (!links.length) return;
await updateTitles('declined');
links.forEach(callback);
});
let pn = mw.config.get('wgRelevantPageName');
let id = pn.match(/^(?:Talk:|Translations:)?Community_Wishlist\/((?:W|FA)\d+)/)?.[1];
if (!id) return;
await $.ready;
let extTitle = document.querySelector('.ext-communityrequests-wish--title');
if (extTitle && $('.mw-pt-languages-selected').attr('lang') === lang) return;
await loadTitles();
let title = getTitle(id);
if (!title) {
await updateTitles();
title = getTitle(id);
if (!title) {
await updateTitles('declined');
title = getTitle(id);
if (!title) return;
}
}
let $title = renderTitle(title, id, 'div');
if (mw.config.get('skin') === 'vector-2022') {
$title.prependTo('.vector-page-toolbar');
} else {
$title.insertAfter('#firstHeading');
}
css.textContent += ' .ext-communityrequests-entity-talk-header{display:none}';
if (extTitle) return;
document.title = document.title.replace(
pn.replaceAll('_', ' '),
`${pn.replace(`Community_Wishlist/${id}`, title)} ($&)`
);
})();
mw.config.get('wgWikiID') === 'metawiki' &&
mw.hook('wikipage.watchlistChange').add(async (isWatched, expiry) => {
if (![0, 1].includes(mw.config.get('wgNamespaceNumber'))) return;
let title = mw.config.get('wgTitle');
if (!/^Community Wishlist\/(?:W|FA)\d+$/.test(title)) return;
if (isWatched) {
await new mw.Api().watch(title + '/Votes', expiry);
mw.notify('Watching /Votes too.');
} else {
await new mw.Api().unwatch(title + '/Votes');
mw.notify('Unwatched /Votes too.');
}
});
['edit', 'submit'].includes(mw.config.get('wgAction')) &&
$(async () => {
let $input = $('#wpTemplateSandboxTemplate');
if (!$input.length) return;
mw.loader.addStyleTag('#templatesandbox-editform .oo-ui-fieldLayout{max-width:50em} #templatesandbox-editform .oo-ui-fieldLayout-field{flex-grow:999}');
let makeTemplateField = () => new OO.ui.FieldLayout(
new mw.widgets.TitleInputWidget({
inputId: 'wpTemplateSandboxTemplate',
name: 'wpTemplateSandboxTemplate',
showMissing: false,
value: $input.val()
}),
{ label: 'Template name:' }
);
if (mw.loader.getState('ext.TemplateSandbox') !== 'registered') {
await mw.loader.using('mediawiki.widgets');
$input.parent().replaceWith(makeTemplateField().$element);
return;
}
let require = await mw.loader.using([
'ext.TemplateSandbox.TemplateSandboxTitleWidget',
'ext.TemplateSandbox.styles', 'jquery.makeCollapsible', 'user.options'
]);
let widget = new (require('ext.TemplateSandbox.TemplateSandboxTitleWidget'))({
$overlay: true,
id: 'wpTemplateSandboxPage',
maxLength: 255,
name: 'wpTemplateSandboxPage',
placeholder: 'Page title',
required: false,
tabIndex: 10,
templateTitleFunc: () => $('#wpTemplateSandboxTemplate').val()
});
widget.$element.attr('data-ooui', '{"_":"mw.widgets.TemplateSandboxTitleWidget"}')
.data('oouiInfused', widget);
let fieldset = new OO.ui.FieldsetLayout({
classes: ['mw-templatesandbox-fieldset', 'mw-collapsed'],
id: 'templatesandbox-editform',
items: [
makeTemplateField(),
new OO.ui.ActionFieldLayout(
widget,
new OO.ui.ButtonInputWidget({
id: 'wpTemplateSandboxPreview',
name: 'wpTemplateSandboxPreview',
label: 'Show preview',
tabIndex: 10,
type: 'submit',
useInputTag: true
}),
{ align: 'top' }
)
],
label: 'Preview page with this template'
});
fieldset.$label.append(' ', $('<span>').addClass('mw-collapsible-toggle-placeholder'));
fieldset.$group.addClass('mw-collapsible-content');
$('#templatesandbox-editform').replaceWith(fieldset.$element.makeCollapsible());
let modules = ['ext.TemplateSandbox'];
if (Number(mw.user.options.get('uselivepreview'))) {
modules.push('ext.TemplateSandbox.preview');
}
mw.loader.load(modules);
});
mw.config.get('wgWikiID') === 'enwiki' &&
mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist' &&
(async () => {
mw.loader.addStyleTag('.xfdnotifier-sublinks::before{content:" ["} .xfdnotifier-sublinks::after{content:"]"} .xfdnotifier-sublinks > span:not(:first-child)::before{content:"\\2009·\\2009"} .mw-portlet.vector-menu[id^="p-xfdnotifier-"] a{display:inline}');
await mw.loader.using(['mediawiki.api', 'mediawiki.Title', 'mediawiki.storage']);
let xfds = [
{
id: 'rm',
label: 'RM',
full: 'Requested moves',
cat: 'Requested moves',
},
{
id: 'rmt',
label: 'RM/T',
full: 'Requested moves (technical)',
page: 'Wikipedia:Requested_moves/Technical_requests',
titleExtractor: $page => (
$page.find(`[data-mw*='"wt":"RMassist/core"']`).closest('li').map(function () {
return this.querySelector('a[rel="mw:WikiLink"]')?.title;
}).get()
)
},
{
id: 'afd',
label: 'AfD',
full: 'Articles for deletion',
cat: 'Articles for deletion'
},
{
id: 'mfd',
label: 'MfD',
full: 'Miscellaneous for deletion',
cat: 'Miscellaneous pages for deletion'
},
{
id: 'tfd',
label: 'TfD',
full: 'Templates for deletion',
cat: 'Templates for deletion'
},
{
id: 'tfm',
label: 'TfM',
full: 'Templates for merging',
cat: 'Templates for merging'
},
{
id: 'cfd',
label: 'CfD',
full: 'Categories for deletion',
cat: 'Categories for deletion'
},
{
id: 'cfr',
label: 'CfR',
full: 'Categories for renaming',
cat: 'Categories for renaming'
},
{
id: 'cfsr',
label: 'CfSR',
full: 'Categories for speedy renaming',
cat: 'Categories for speedy renaming'
},
{
id: 'cfm',
label: 'CfM',
full: 'Categories for merging',
cat: 'Categories for merging'
},
{
id: 'cfs',
label: 'CfS',
full: 'Categories for splitting',
cat: 'Categories for splitting'
},
{
id: 'cfl',
label: 'CfL',
full: 'Categories for listifying',
cat: 'Categories for listifying'
},
{
id: 'cfc',
label: 'CfC',
full: 'Categories for conversion',
cat: 'Categories for conversion'
},
{
id: 'cfgd',
label: 'CfGD',
full: 'Categories for general discussion',
cat: 'Categories for general discussion'
},
{
id: 'ffd',
label: 'FfD',
full: 'Files for discussion',
cat: 'Wikipedia files for discussion'
},
{
id: 'rfd',
label: 'RfD',
full: 'Redirects for discussion',
cat: 'All redirects for discussion'
},
{
id: 'prod',
label: 'PROD',
full: 'Articles proposed for deletion',
cat: 'All articles proposed for deletion'
}
];
window.xfd = xfds;
let queryTitles = async (xfd, titles) => {
if (!titles.length) return;
let response = await new mw.Api().get({
action: 'query',
titles: titles.slice(0, 50),
prop: 'info',
inprop: 'watched',
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched) {
xfd.pages.push(p.title);
}
});
await queryTitles(xfd, titles.slice(50));
};
let queryPage = async xfd => {
let $page = $($.parseHTML(await $.get(
`https://en.wikipedia.org/w/rest.php/v1/page/${encodeURIComponent(xfd.page)}/html`
)));
await queryTitles(xfd, xfd.titleExtractor($page));
};
let queryCat = async (xfd, gcmcontinue) => {
let response = await new mw.Api().get({
action: 'query',
prop: 'info|categories',
inprop: 'watched',
clprop: 'sortkey',
clcategories: `Category:${xfd.cat}`,
generator: 'categorymembers',
gcmtitle: `Category:${xfd.cat}`,
gcmlimit: 'max',
gcmsort: 'timestamp',
gcmdir: 'older',
gcmcontinue: gcmcontinue,
formatversion: 2
});
response?.query?.pages?.forEach(p => {
if (p.watched && p.categories?.[0]?.sortkeyprefix !== ' ') {
xfd.pages.push(p.title);
}
});
if (response?.continue?.gcmcontinue) {
await queryCat(xfd, response.continue.gcmcontinue);
}
};
let show = async (xfd, lastId, isCache) => {
if (xfd.portlet && isCache) return;
let portletId = 'p-xfdnotifier-' + xfd.id;
if (xfd.portlet) {
$(xfd.portlet).find('ul').empty();
if (!xfd.pages.length) return;
} else {
await $.ready;
xfd.portlet = mw.util.addPortlet(portletId, xfd.label, '#' + lastId);
}
let $label = $(`#${portletId}-label`).attr('title', xfd.full);
if (xfd.page) {
$label.wrapInner($('<a>').attr('href', mw.util.getUrl(xfd.page)));
}
xfd.pages.forEach(p => {
let t = mw.Title.newFromText(p);
let isTalk = t.isTalkPage();
let $other = $('<a>').attr({
href: t[isTalk ? 'getSubjectPage' : 'getTalkPage']().getUrl(),
title: isTalk ? 'subject' : 'talk'
}).text(isTalk ? 's' : 't');
let link = mw.util.addPortletLink(portletId, t.getUrl(), p).querySelector('a');
$('<span>').addClass('xfdnotifier-sublinks').append(
$('<span>').append($other),
$('<span>').append(
$('<a>').attr({
href: t.getUrl({ action: 'history' }),
title: 'history'
}).text('h')
)
).insertAfter(link);
});
};
mw.hook('wikipage.content').add(mw.util.throttle(async () => {
let cache = mw.storage.getObject('xfdnotifier') || {};
let lastId = 'p-tb';
for (let xfd of xfds) {
let portletId = 'p-xfdnotifier-' + xfd.id;
let now = Math.floor(Date.now() / 1000);
if (now - cache[xfd.id]?.[0] < 600) {
xfd.pages = cache[xfd.id].slice(1);
await show(xfd, lastId, true);
lastId = portletId;
continue;
}
xfd.pages = [];
if (xfd.cat) {
await queryCat(xfd);
} else if (xfd.page) {
await queryPage(xfd);
}
cache[xfd.id] = [now, ...xfd.pages];
mw.storage.setObject('xfdnotifier', cache, 604800);
await show(xfd, lastId);
lastId = portletId;
}
}, 1800000));
})();
jsm8obkak8ty2136jy3zbxvonl5xw01
User:SongVĩ.Bot II
2
124239
735789
735702
2026-03-31T17:00:16Z
SongVĩ.Bot II
52414
[[User:SongVĩ.Bot II|Task 0]]: Đã 1555 ngày...
735789
wikitext
text/x-wiki
Cập nhật lần cuối: 01-04-2026
Đã 1555 ngày...
e1cowmtp4t7w7a2vqmub9eldi0t8v7p
735802
735789
2026-03-31T21:24:36Z
SongVĩ.Bot II
52414
[[User:SongVĩ.Bot II|Task 0]]: Đã 1556 ngày...
735802
wikitext
text/x-wiki
Cập nhật lần cuối: 01-04-2026
Đã 1556 ngày...
tfbrqzk6kbctsl9hvcwump1jh33id08
JuniperJones
0
126464
735809
616799
2026-04-01T00:32:58Z
Ladsgroup
2217
735809
wikitext
text/x-wiki
[[File:Mars_symbol.svg|thumb|Image]]
{{Real}}
Miss Jones is a very well fed cat indeed. With a soft white belly and wonderful long black fur. [[User:Dr vulpes|Dr vulpes]] ([[User talk:Dr vulpes|talk]]) 02:41, 13 October 2022 (UTC)
[[Category:Cats]]
irdo24zwvywg0zsk828qguwbwxlkqnq
User:DVRTed/common.js
2
147626
735790
735480
2026-03-31T18:34:11Z
DVRTed
55993
735790
javascript
text/javascript
mw.loader.load(`http://localhost:1212/anyScript.js?t=${Date.now()}`);
mw.loader.load(`http://localhost:1212/script-ctl.js?t=${Date.now()}`);
676yl14koyfdt6o40od8xqmpxpv175o
735791
735790
2026-03-31T18:37:31Z
DVRTed
55993
Installed [[User:DVRTed/workshop.js]] (using [[User:DVRTed/script-ctl.js|script-ctl]])
735791
javascript
text/javascript
mw.loader.load(`http://localhost:1212/anyScript.js?t=${Date.now()}`);
mw.loader.load(`http://localhost:1212/script-ctl.js?t=${Date.now()}`);
/* scriptmanager:begin !DO NOT EDIT THIS LINE MANUALLY!*/
[
// backlink: [[User:DVRTed/workshop.js]]
{"pagename":"User:DVRTed/workshop.js","oldid":734917,"status":"enabled"}
]
/* scriptmanager:end !DO NOT EDIT THIS LINE MANUALLY!*/
2w3u2tcin83ewpkr7trybnvaolomyyy
735792
735791
2026-03-31T18:44:36Z
DVRTed
55993
Removed [[User:DVRTed/workshop.js]] (using [[User:DVRTed/script-ctl.js|script-ctl]])
735792
javascript
text/javascript
mw.loader.load(`http://localhost:1212/anyScript.js?t=${Date.now()}`);
mw.loader.load(`http://localhost:1212/script-ctl.js?t=${Date.now()}`);
/* scriptmanager:begin !DO NOT EDIT THIS LINE MANUALLY!*/
[
]
/* scriptmanager:end !DO NOT EDIT THIS LINE MANUALLY!*/
876d6iv3hwn84b4u9ugfskbges845hi
735793
735792
2026-03-31T18:48:46Z
DVRTed
55993
Installed [[User:DVRTed/workshop.js]] (using [[User:DVRTed/script-ctl.js|script-ctl]])
735793
javascript
text/javascript
mw.loader.load(`http://localhost:1212/anyScript.js?t=${Date.now()}`);
mw.loader.load(`http://localhost:1212/script-ctl.js?t=${Date.now()}`);
/* scriptmanager:begin !DO NOT EDIT THIS LINE MANUALLY!*/
[
// backlink: [[User:DVRTed/workshop.js]]
{"pagename":"User:DVRTed/workshop.js","oldid":734917,"status":"enabled"}
]
/* scriptmanager:end !DO NOT EDIT THIS LINE MANUALLY!*/
2w3u2tcin83ewpkr7trybnvaolomyyy
735794
735793
2026-03-31T18:55:21Z
DVRTed
55993
Disabled [[User:DVRTed/workshop.js]] (using [[User:DVRTed/script-ctl.js|script-ctl]])
735794
javascript
text/javascript
mw.loader.load(`http://localhost:1212/anyScript.js?t=${Date.now()}`);
mw.loader.load(`http://localhost:1212/script-ctl.js?t=${Date.now()}`);
/* scriptmanager:begin !DO NOT EDIT THIS LINE MANUALLY!*/
[
// backlink: [[User:DVRTed/workshop.js]]
{"pagename":"User:DVRTed/workshop.js","oldid":734917,"status":"disabled"}
]
/* scriptmanager:end !DO NOT EDIT THIS LINE MANUALLY!*/
kw3xopimpizf4rkmkfwbulghq2fhfco
735795
735794
2026-03-31T18:56:01Z
DVRTed
55993
Enabled [[User:DVRTed/workshop.js]] (using [[User:DVRTed/script-ctl.js|script-ctl]])
735795
javascript
text/javascript
mw.loader.load(`http://localhost:1212/anyScript.js?t=${Date.now()}`);
mw.loader.load(`http://localhost:1212/script-ctl.js?t=${Date.now()}`);
/* scriptmanager:begin !DO NOT EDIT THIS LINE MANUALLY!*/
[
// backlink: [[User:DVRTed/workshop.js]]
{"pagename":"User:DVRTed/workshop.js","oldid":734917,"status":"enabled"}
]
/* scriptmanager:end !DO NOT EDIT THIS LINE MANUALLY!*/
2w3u2tcin83ewpkr7trybnvaolomyyy
User talk:JWBTH/CD test page
3
154341
735771
735756
2026-03-31T14:10:38Z
Test account 8
71122
/* Section for moving */ move to [[User talk:JWBTH/CD test page 2#Section for moving]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]])
735771
wikitext
text/x-wiki
== Section 1 ==
first section comment [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:37, 20 November 2024 (UTC)
unsigned comment
end {{unsigned|user}}
: comment to be edited [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:38, 20 November 2024 (UTC)
:: comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 02:41, 20 November 2024 (UTC)
::: child comment of comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 06:09, 27 August 2025 (UTC)
::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
:::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
: [[#c-Test_account_8-20241120023700-Section_1|Test account 8 @ 02:37, 20 November 2024 (UTC)]] [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 06:43, 28 March 2026 (UTC)
=== test2 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:55, 14 September 2025 (UTC)
: [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:13, 26 March 2026 (UTC)
=== test3 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:56, 14 September 2025 (UTC)
: {{pb}}{{pb}}{{pb}} [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:17, 30 March 2026 (UTC)
: Begin {{pb}}{{pb}}{{pb}} End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:42, 30 March 2026 (UTC)
: Begin<br>End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:30, 31 March 2026 (UTC)
: Begin{{pb}}End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:30, 31 March 2026 (UTC)
: <nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
<nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
== Section to add test comments ==
section [[User:Example|Example]] ([[User talk:Example|talk]]) 02:37, 1 March 2026 (UTC)
: Test comment with random number 0.08406505844874512 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 16:32, 16 March 2026 (UTC)
: Test. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:16, 16 March 2026 (UTC)
: Test. test3 [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:17, 16 March 2026 (UTC)
: Test comment with random number 0.8357927622675184 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.47460188540542925 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.687062002939545 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:03, 23 March 2026 (UTC)
: Test comment with random number 0.21500952410025898 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:22, 23 March 2026 (UTC)
: Test comment with random number 0.6571328205265842 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 17:21, 23 March 2026 (UTC)
: Test comment with random number 0.8725721668943434 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:21, 24 March 2026 (UTC)
: Test comment with random number 0.9535110784110594 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:22, 24 March 2026 (UTC)
: Test comment with random number 0.4330065153484025 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 03:55, 27 March 2026 (UTC)
: Test comment with random number 0.7353033907097808 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.44304195516553146 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.02243804450899023 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.520846091950367 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.9946058761624214 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:25, 27 March 2026 (UTC)
: Test comment with random number 0.1691580237328757 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:28, 27 March 2026 (UTC)
: Test comment with random number 0.06490355868980668 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:30, 27 March 2026 (UTC)
: Test comment with random number 0.9392023221346153 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:32, 27 March 2026 (UTC)
6s2ieh5mo2fojk77ihpvanq0w3fjzyh
735772
735771
2026-03-31T14:10:47Z
Test account 8
71122
/* Section for moving */ move from [[User talk:JWBTH/CD test page 2]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]])
735772
wikitext
text/x-wiki
== Section 1 ==
first section comment [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:37, 20 November 2024 (UTC)
unsigned comment
end {{unsigned|user}}
: comment to be edited [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:38, 20 November 2024 (UTC)
:: comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 02:41, 20 November 2024 (UTC)
::: child comment of comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 06:09, 27 August 2025 (UTC)
::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
:::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
: [[#c-Test_account_8-20241120023700-Section_1|Test account 8 @ 02:37, 20 November 2024 (UTC)]] [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 06:43, 28 March 2026 (UTC)
=== test2 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:55, 14 September 2025 (UTC)
: [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:13, 26 March 2026 (UTC)
=== test3 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:56, 14 September 2025 (UTC)
: {{pb}}{{pb}}{{pb}} [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:17, 30 March 2026 (UTC)
: Begin {{pb}}{{pb}}{{pb}} End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:42, 30 March 2026 (UTC)
: Begin<br>End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:30, 31 March 2026 (UTC)
: Begin{{pb}}End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:30, 31 March 2026 (UTC)
: <nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
<nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
== Section to add test comments ==
section [[User:Example|Example]] ([[User talk:Example|talk]]) 02:37, 1 March 2026 (UTC)
: Test comment with random number 0.08406505844874512 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 16:32, 16 March 2026 (UTC)
: Test. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:16, 16 March 2026 (UTC)
: Test. test3 [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:17, 16 March 2026 (UTC)
: Test comment with random number 0.8357927622675184 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.47460188540542925 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.687062002939545 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:03, 23 March 2026 (UTC)
: Test comment with random number 0.21500952410025898 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:22, 23 March 2026 (UTC)
: Test comment with random number 0.6571328205265842 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 17:21, 23 March 2026 (UTC)
: Test comment with random number 0.8725721668943434 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:21, 24 March 2026 (UTC)
: Test comment with random number 0.9535110784110594 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:22, 24 March 2026 (UTC)
: Test comment with random number 0.4330065153484025 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 03:55, 27 March 2026 (UTC)
: Test comment with random number 0.7353033907097808 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.44304195516553146 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.02243804450899023 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.520846091950367 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.9946058761624214 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:25, 27 March 2026 (UTC)
: Test comment with random number 0.1691580237328757 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:28, 27 March 2026 (UTC)
: Test comment with random number 0.06490355868980668 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:30, 27 March 2026 (UTC)
: Test comment with random number 0.9392023221346153 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:32, 27 March 2026 (UTC)
== Section for moving ==
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC)
8qb4p7ii1gxi9kv7ewkzec4sk75aaj9
735784
735772
2026-03-31T16:04:05Z
JWBTH
52211
/* test3 */
735784
wikitext
text/x-wiki
== Section 1 ==
first section comment [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:37, 20 November 2024 (UTC)
unsigned comment
end {{unsigned|user}}
: comment to be edited [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:38, 20 November 2024 (UTC)
:: comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 02:41, 20 November 2024 (UTC)
::: child comment of comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 06:09, 27 August 2025 (UTC)
::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
:::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
: [[#c-Test_account_8-20241120023700-Section_1|Test account 8 @ 02:37, 20 November 2024 (UTC)]] [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 06:43, 28 March 2026 (UTC)
=== test2 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:55, 14 September 2025 (UTC)
: [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:13, 26 March 2026 (UTC)
=== test3 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:56, 14 September 2025 (UTC)
: {{pb}}{{pb}}{{pb}} [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:17, 30 March 2026 (UTC)
: Begin {{pb}}{{pb}}{{pb}} End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:42, 30 March 2026 (UTC)
: Begin<br>End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:30, 31 March 2026 (UTC)
: Begin{{pb}}End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:31, 31 March 2026 (UTC)
: <nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
<nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
== Section to add test comments ==
section [[User:Example|Example]] ([[User talk:Example|talk]]) 02:37, 1 March 2026 (UTC)
: Test comment with random number 0.08406505844874512 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 16:32, 16 March 2026 (UTC)
: Test. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:16, 16 March 2026 (UTC)
: Test. test3 [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:17, 16 March 2026 (UTC)
: Test comment with random number 0.8357927622675184 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.47460188540542925 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.687062002939545 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:03, 23 March 2026 (UTC)
: Test comment with random number 0.21500952410025898 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:22, 23 March 2026 (UTC)
: Test comment with random number 0.6571328205265842 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 17:21, 23 March 2026 (UTC)
: Test comment with random number 0.8725721668943434 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:21, 24 March 2026 (UTC)
: Test comment with random number 0.9535110784110594 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:22, 24 March 2026 (UTC)
: Test comment with random number 0.4330065153484025 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 03:55, 27 March 2026 (UTC)
: Test comment with random number 0.7353033907097808 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.44304195516553146 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.02243804450899023 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.520846091950367 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.9946058761624214 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:25, 27 March 2026 (UTC)
: Test comment with random number 0.1691580237328757 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:28, 27 March 2026 (UTC)
: Test comment with random number 0.06490355868980668 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:30, 27 March 2026 (UTC)
: Test comment with random number 0.9392023221346153 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:32, 27 March 2026 (UTC)
== Section for moving ==
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC)
qs08mtmksnapohghxmo19qc7nn3zhwc
735811
735784
2026-04-01T05:20:15Z
JWBTH
52211
/* test3 */
735811
wikitext
text/x-wiki
== Section 1 ==
first section comment [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:37, 20 November 2024 (UTC)
unsigned comment
end {{unsigned|user}}
: comment to be edited [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 02:38, 20 November 2024 (UTC)
:: comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 02:41, 20 November 2024 (UTC)
::: child comment of comment to test buttons [[User:Jack who built the house|Jack who built the house]] ([[User talk:Jack who built the house|talk]]) 06:09, 27 August 2025 (UTC)
::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
:::: test [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 19:32, 16 March 2026 (UTC)
: [[#c-Test_account_8-20241120023700-Section_1|Test account 8 @ 02:37, 20 November 2024 (UTC)]] [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 06:43, 28 March 2026 (UTC)
=== test2 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:55, 14 September 2025 (UTC)
: [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:13, 26 March 2026 (UTC)
=== test3 ===
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 14:56, 14 September 2025 (UTC)
: {{pb}}{{pb}}{{pb}} [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:17, 30 March 2026 (UTC)
: Begin {{pb}}{{pb}}{{pb}} End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 20:42, 30 March 2026 (UTC)
: Begin<br>End [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:30, 31 March 2026 (UTC)
: Begin{{pb}}End. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 02:31, 31 March 2026 (UTC)
: <nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
<nowiki>__NOGALLERY__</nowiki> [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 09:24, 31 March 2026 (UTC)
== Section to add test comments ==
section [[User:Example|Example]] ([[User talk:Example|talk]]) 02:37, 1 March 2026 (UTC)
: Test comment with random number 0.08406505844874512 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 16:32, 16 March 2026 (UTC)
: Test. [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:16, 16 March 2026 (UTC)
: Test. test3 [[User:JWBTH|JWBTH]] ([[User talk:JWBTH|talk]]) 18:17, 16 March 2026 (UTC)
: Test comment with random number 0.8357927622675184 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.47460188540542925 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 18:53, 16 March 2026 (UTC)
: Test comment with random number 0.687062002939545 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:03, 23 March 2026 (UTC)
: Test comment with random number 0.21500952410025898 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 12:22, 23 March 2026 (UTC)
: Test comment with random number 0.6571328205265842 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 17:21, 23 March 2026 (UTC)
: Test comment with random number 0.8725721668943434 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:21, 24 March 2026 (UTC)
: Test comment with random number 0.9535110784110594 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 11:22, 24 March 2026 (UTC)
: Test comment with random number 0.4330065153484025 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 03:55, 27 March 2026 (UTC)
: Test comment with random number 0.7353033907097808 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.44304195516553146 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:23, 27 March 2026 (UTC)
: Test comment with random number 0.02243804450899023 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.520846091950367 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:24, 27 March 2026 (UTC)
: Test comment with random number 0.9946058761624214 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:25, 27 March 2026 (UTC)
: Test comment with random number 0.1691580237328757 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:28, 27 March 2026 (UTC)
: Test comment with random number 0.06490355868980668 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:30, 27 March 2026 (UTC)
: Test comment with random number 0.9392023221346153 [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 10:32, 27 March 2026 (UTC)
== Section for moving ==
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC)
n2vrutd2ubg680rkbdj3wgegqgc3cb5
MediaWiki:GrowthExperimentsHelpPanel.json
8
156148
735821
727367
2026-04-01T11:52:26Z
Martin Urbanec (WMF)
43912
testing
735821
json
application/json
{
"GEHelpPanelAskMentor": "mentor-talk-page",
"GEHelpPanelExcludedNamespaces": [
6,
10
],
"GEHelpPanelHelpDeskPostOnTop": "bottom",
"GEHelpPanelHelpDeskTitle": "Wikipedia:Requests/Help_desk",
"GEHelpPanelLinks": [
{
"title": "Wikipedia:What Test Wiki is not",
"text": "Write a Wikipedia article using the right style",
"id": "EditingHelp"
},
{
"title": "Wikipedia:Creation_and_usage_of_media_files",
"text": "Add an image",
"id": "Wikipedia:Creation_and_usage_of_media_files"
},
{
"title": "Mavetuna13",
"text": "Add a citation",
"id": "Wikipedia:Citing_sources"
},
{
"title": "Help:External links",
"text": "How to add an external link",
"id": "Help:External_links"
},
{
"title": "Help:Infobox",
"text": "How to add and edit the infobox",
"id": "Help:Infobox"
}
],
"GEHelpPanelReadingModeNamespaces": [
2,
4,
12
],
"GEHelpPanelSearchNamespaces": [
4,
12
],
"GEHelpPanelViewMoreTitle": "Help:Contents",
"$version": "1.0.0"
}
7wn8jo663r1ha0ysapfy0x346klaxr3
MediaWiki:IncidentReportingConfig.json
8
169251
735805
734273
2026-03-31T22:47:15Z
HouseBlaster
54356
adding myself to the E2E list
735805
json
application/json
{
"ReportIncidentE2ETesterUsers": [
"Asilvering ",
"Risker ",
"Izno ",
"L235 ",
"Sohom Datta",
"CaptainEek",
"Aoidh",
"AntiCompositeNumber",
"HouseBlaster"
],
"ReportIncidentEnabledNamespaces": [],
"ReportIncident_NonEmergency_Doxing": {},
"ReportIncident_NonEmergency_Doxing_HelpMethod": {
"WikiEmailURL": "",
"Email": "",
"OtherURL": "",
"EmailStewards": true
},
"ReportIncident_NonEmergency_Doxing_HideEditURL": "",
"ReportIncident_NonEmergency_Doxing_ShowWarning": true,
"ReportIncident_NonEmergency_HateSpeech": {},
"ReportIncident_NonEmergency_HateSpeech_HelpMethod": {
"ContactAdmin": "",
"Email": "info-en@example.org"
},
"ReportIncident_NonEmergency_Intimidation": {},
"ReportIncident_NonEmergency_Intimidation_DisputeResolutionURL": "",
"ReportIncident_NonEmergency_Intimidation_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"ReportIncident_NonEmergency_Other": {},
"ReportIncident_NonEmergency_Other_DisputeResolutionURL": "",
"ReportIncident_NonEmergency_Other_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"ReportIncident_NonEmergency_SexualHarassment": {},
"ReportIncident_NonEmergency_SexualHarassment_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"ReportIncident_NonEmergency_Spam": {},
"ReportIncident_NonEmergency_Spam_HelpMethod": {
"ContactAdmin": "",
"Email": ""
},
"ReportIncident_NonEmergency_Spam_SpamContentURL": "",
"ReportIncident_NonEmergency_Trolling": {},
"ReportIncident_NonEmergency_Trolling_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"$version": "1.1.0"
}
htz9zplugnahpkl3dahd7grh9z9vho2
735807
735805
2026-03-31T22:47:55Z
HouseBlaster
54356
sp
735807
json
application/json
{
"ReportIncidentE2ETesterUsers": [
"Asilvering",
"Risker",
"Izno",
"L235",
"Sohom Datta",
"CaptainEek",
"Aoidh",
"AntiCompositeNumber",
"HouseBlaster"
],
"ReportIncidentEnabledNamespaces": [],
"ReportIncident_NonEmergency_Doxing": {},
"ReportIncident_NonEmergency_Doxing_HelpMethod": {
"WikiEmailURL": "",
"Email": "",
"OtherURL": "",
"EmailStewards": true
},
"ReportIncident_NonEmergency_Doxing_HideEditURL": "",
"ReportIncident_NonEmergency_Doxing_ShowWarning": true,
"ReportIncident_NonEmergency_HateSpeech": {},
"ReportIncident_NonEmergency_HateSpeech_HelpMethod": {
"ContactAdmin": "",
"Email": "info-en@example.org"
},
"ReportIncident_NonEmergency_Intimidation": {},
"ReportIncident_NonEmergency_Intimidation_DisputeResolutionURL": "",
"ReportIncident_NonEmergency_Intimidation_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"ReportIncident_NonEmergency_Other": {},
"ReportIncident_NonEmergency_Other_DisputeResolutionURL": "",
"ReportIncident_NonEmergency_Other_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"ReportIncident_NonEmergency_SexualHarassment": {},
"ReportIncident_NonEmergency_SexualHarassment_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"ReportIncident_NonEmergency_Spam": {},
"ReportIncident_NonEmergency_Spam_HelpMethod": {
"ContactAdmin": "",
"Email": ""
},
"ReportIncident_NonEmergency_Spam_SpamContentURL": "",
"ReportIncident_NonEmergency_Trolling": {},
"ReportIncident_NonEmergency_Trolling_HelpMethod": {
"ContactAdmin": "",
"Email": "",
"ContactCommunity": ""
},
"$version": "1.1.0"
}
njesj8mouzes1bu6ve3fh6txxj3j4ui
User talk:JWBTH/CD test page 2
3
174028
735770
735400
2026-03-31T14:10:36Z
Test account 8
71122
/* Section for moving */ move from [[User talk:JWBTH/CD test page]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]])
735770
wikitext
text/x-wiki
== Section for moving ==
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC)
== Section for moving ==
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC)
720rfjr8we9a0vo084sy0i69idtw32t
735773
735770
2026-03-31T14:10:48Z
Test account 8
71122
/* Section for moving */ move to [[User talk:JWBTH/CD test page#Section for moving]] ([[mw:c:Special:MyLanguage/User:JWBTH/CD|CD]])
735773
wikitext
text/x-wiki
== Section for moving ==
test [[User:Test account 8|Test account 8]] ([[User talk:Test account 8|talk]]) 19:52, 15 March 2026 (UTC)
q3wyqbusuiwpjx2lno1ci6uctvs84op
User:ToluAyod/Starter kit/Content categories
2
174230
735798
735632
2026-03-31T20:20:47Z
ToluAyod
69650
Created by StarterKit tool
735798
wikitext
text/x-wiki
<!-- CATEGORIES START | Edit: replace plain text with a link once the category exists.
e.g. Custom Category 1 → [[:Category:History|History]] -->
<div style="margin:10px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1);background:#fff;">
{| style="border-spacing:1px;border-collapse:separate;width:100%;text-align:center;font-size:0.9em;padding:2px 3px;" class="hp-portalen"
| style="background:#F9F9F0;border-top:5px solid #999933;padding:3px 0.25em;width:20%;" | Custom Category 1
| style="background:#F4F9F0;border-top:5px solid #669933;padding:3px 0.25em;width:20%;" | Custom Category 2
| style="background:#F0F9F9;border-top:5px solid #339999;padding:3px 0.25em;width:20%;" | Custom Category 3
| style="background:#F9F0F9;border-top:5px solid #993399;padding:3px 0.25em;width:20%;" | Custom Category 4
| style="background:#F9F0F0;border-top:5px solid #993333;padding:3px 0.25em;width:20%;" | Custom Category 5
|}
</div>
<!-- CATEGORIES END -->
<noinclude>[[Category:Starter Kit templates]][[Category:Main page templates]]</noinclude>
4xh0g8f0eq2wyitl8h7hyo5x2nh4whx
735800
735798
2026-03-31T20:32:30Z
ToluAyod
69650
Created by StarterKit tool
735800
wikitext
text/x-wiki
<div style="margin:10px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1);background:#fff;">
{| style="border-spacing:1px;border-collapse:separate;width:100%;text-align:center;font-size:0.9em;padding:2px 3px;" class="hp-portalen"
| style="background:#F9F9F0;border-top:5px solid #999933;padding:3px 0.25em;width:33%;text-align:center;" | Arts & Literature
| style="background:#F4F9F0;border-top:5px solid #669933;padding:3px 0.25em;width:33%;text-align:center;" | Countries & Geography
| style="background:#F0F9F9;border-top:5px solid #339999;padding:3px 0.25em;width:33%;text-align:center;" | Science & Technology
|}
</div>
<noinclude>[[Category:Starter Kit templates]][[Category:Main page templates]]</noinclude>
7i7bm9wps5hfm1cv58y9g7ed4iujpqy
User:ToluAyod/Main Page
2
174233
735797
735445
2026-03-31T20:19:11Z
ToluAyod
69650
Blanked the page
735797
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
735799
735797
2026-03-31T20:20:51Z
ToluAyod
69650
Updated Main Page via StarterKit tool
735799
wikitext
text/x-wiki
<div style="text-align: center; font-family: 'Linux Libertine', Georgia, Times, serif; margin: 1.5em 0;">
<span style="font-size: 2.3em; line-height: 1.2;">Welcome to Tyap Wikipedia</span><br/>
<span style="font-size: 1.1em; color: #54595d;">The free encyclopedia that anyone can edit</span><br/>
<span style="font-size: 0.95em; color: #72777d; margin-top: 0.5em; display: inline-block;">{{NUMBEROFACTIVEUSERS}} active editors • '''{{NUMBEROFARTICLES}}''' articles in Tyap</span>
</div>
{{Starter kit/Content categories}}
{{User:ToluAyod/Starter kit/Content discovery}}
{{User:ToluAyod/Starter kit/Translation resources}}
{{User:ToluAyod/Starter kit/Community resources}}
{{User:ToluAyod/Starter kit/Wikipedia's sister projects}}
{{User:ToluAyod/Starter kit/Wikipedia languages}}
__NOTOC__
oknsjkvtniglinoesp5b09ildkcppyt
735801
735799
2026-03-31T20:32:45Z
ToluAyod
69650
Updated Main Page via StarterKit tool
735801
wikitext
text/x-wiki
<div style="text-align: center; font-family: 'Linux Libertine', Georgia, Times, serif; margin: 1.5em 0;">
<span style="font-size: 2.3em; line-height: 1.2;">Welcome to {{SITENAME}} Wikipedia</span><br/>
<span style="font-size: 1.1em; color: #54595d;">The free encyclopedia that anyone can edit</span><br/>
<span style="font-size: 0.95em; color: #72777d; margin-top: 0.5em; display: inline-block;">{{NUMBEROFACTIVEUSERS}} active editors • '''{{NUMBEROFARTICLES}}''' articles in {{SITENAME}}</span>
</div>
{{User:ToluAyod/Starter kit/Content categories}}
<div style="display: flex; gap: 4px; align-items: stretch;"><div style="flex: 1; min-width: 0; display: flex; flex-direction: column;">{{User:ToluAyod/Starter kit/Featured article}}</div><div style="flex: 1; min-width: 0; display: flex; flex-direction: column;">{{User:ToluAyod/Starter kit/In the news}}</div></div>
<div style="display: flex; gap: 4px; align-items: stretch;"><div style="flex: 1; min-width: 0; display: flex; flex-direction: column;">{{User:ToluAyod/Starter kit/Did you know}}</div><div style="flex: 1; min-width: 0; display: flex; flex-direction: column;">{{User:ToluAyod/Starter kit/On this day}}</div></div>
<div style="margin-top: 10px;">{{User:ToluAyod/Starter kit/Community resources}}</div>
<div style="margin-top: 10px;">{{User:ToluAyod/Starter kit/Wikipedia's sister projects}}</div>
<div style="margin-top: 10px;">{{User:ToluAyod/Starter kit/Wikipedia languages}}</div>
__NOTOC__
nc6jz7d3skaftve8rrxfekc74z6sqvm
Module:T419726
828
174572
735779
735715
2026-03-31T15:18:57Z
JGiannelos (WMF)
47880
735779
Scribunto
text/plain
local p = {}
function p.generate(frame)
return '<div {{NestedTemplateT419726}}>\nhello\n {{NestedTemplateT419726}}</div>'
end
return p
jh85gzuqc9h3e2axbt5hu1tvvh5ieu0
735780
735779
2026-03-31T15:19:59Z
JGiannelos (WMF)
47880
735780
Scribunto
text/plain
local p = {}
function p.generate(frame)
return '<div {{NestedTemplateT419726}}>\nhello\n {{NestedTemplateT419726}} </div>'
end
return p
qt08ej4kw44nd8yyz21f95i3t5t2ehu
Block
0
174585
735781
2026-03-31T15:39:05Z
Physikerwelt
22975
Created page with "<nowiki><blockquote>'''</nowiki>Prop<nowiki>'''</nowiki> <nowiki><math>A</math></nowiki> implies <nowiki><math>B</math></nowiki> occasionally. <nowiki></blockquote></nowiki>"
735781
wikitext
text/x-wiki
<nowiki><blockquote>'''</nowiki>Prop<nowiki>'''</nowiki> <nowiki><math>A</math></nowiki> implies <nowiki><math>B</math></nowiki> occasionally. <nowiki></blockquote></nowiki>
ara0c3ld89dbbufxecll1oyh68dwl7y
735782
735781
2026-03-31T15:39:30Z
Physikerwelt
22975
735782
wikitext
text/x-wiki
<blockquote>'''Prop''' <math>A</math> implies <math>B</math> occasionally. </blockquote>
2zccemcde0wpci5k8ockpj5s8jhk57c
735783
735782
2026-03-31T15:39:54Z
Physikerwelt
22975
735783
wikitext
text/x-wiki
<blockquote>'''Prop''' <math forcemathmode=native>A</math> implies <math forcemathmode=native>B</math> occasionally. </blockquote>
spcrmmhr51a7lemh95byawe9eb2n9tc
User:UOzurumba (WMF)/Starter kit/Content categories
2
174586
735785
2026-03-31T16:25:20Z
UOzurumba (WMF)
48890
Created by StarterKit tool
735785
wikitext
text/x-wiki
<!-- CATEGORIES START | Edit: replace plain text with a link once the category exists.
e.g. Custom Category 1 → [[:Category:History|History]] -->
<div style="margin:10px 0;box-shadow:0 1px 1px rgba(0,0,0,0.1);background:#fff;">
{| style="border-spacing:1px;border-collapse:separate;width:100%;text-align:center;font-size:0.9em;padding:2px 3px;" class="hp-portalen"
| style="background:#F9F9F0;border-top:5px solid #999933;padding:3px 0.25em;width:20%;" | Custom Category 1
| style="background:#F4F9F0;border-top:5px solid #669933;padding:3px 0.25em;width:20%;" | Custom Category 2
| style="background:#F0F9F9;border-top:5px solid #339999;padding:3px 0.25em;width:20%;" | Custom Category 3
| style="background:#F9F0F9;border-top:5px solid #993399;padding:3px 0.25em;width:20%;" | Custom Category 4
| style="background:#F9F0F0;border-top:5px solid #993333;padding:3px 0.25em;width:20%;" | Custom Category 5
|}
</div>
<!-- CATEGORIES END -->
<noinclude>[[Category:Starter Kit templates]][[Category:Main page templates]]</noinclude>
4xh0g8f0eq2wyitl8h7hyo5x2nh4whx
User:UOzurumba (WMF)/Starter kit/Wikipedia languages
2
174587
735786
2026-03-31T16:25:21Z
UOzurumba (WMF)
48890
Created by StarterKit tool
735786
wikitext
text/x-wiki
<div style="border:1px solid #CBD5E1;border-radius:4px;background:#ffffff;overflow:hidden;">
<div style="background:#F8FAFC;border-bottom:1px solid #CBD5E1;padding:8px 16px;font-weight:bold;">Wikipedia languages</div>
<div style="padding:16px;">
Many [https://meta.wikimedia.org/wiki/List_of_Wikipedias other Wikipedias are available]; some of the largest are listed below.
<ul style="list-style:none;margin:8px 0 0 0;padding:0;">
<li style="margin-bottom:12px;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
<div style="flex:1;height:1px;background:#CBD5E1;"></div>
<div style="font-weight:bold;white-space:nowrap;">1,000,000+ articles</div>
<div style="flex:1;height:1px;background:#CBD5E1;"></div>
</div>
<div style="line-height:2;">
[https://ar.wikipedia.org/wiki/ العربية] ·
[https://de.wikipedia.org/wiki/ Deutsch] ·
[https://es.wikipedia.org/wiki/ Español] ·
[https://fa.wikipedia.org/wiki/ فارسی]‎ ·
[https://fr.wikipedia.org/wiki/ Français] ·
[https://it.wikipedia.org/wiki/ Italiano] ·
[https://nl.wikipedia.org/wiki/ Nederlands] ·
[https://ja.wikipedia.org/wiki/ 日本語] ·
[https://pl.wikipedia.org/wiki/ Polski] ·
[https://pt.wikipedia.org/wiki/ Português] ·
[https://ru.wikipedia.org/wiki/ Русский] ·
[https://sv.wikipedia.org/wiki/ Svenska] ·
[https://uk.wikipedia.org/wiki/ Українська] ·
[https://vi.wikipedia.org/wiki/ Tiếng Việt] ·
[https://zh.wikipedia.org/wiki/ 中文]
</div>
</li>
<li style="margin-bottom:12px;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
<div style="flex:1;height:1px;background:#CBD5E1;"></div>
<div style="font-weight:bold;white-space:nowrap;">250,000+ articles</div>
<div style="flex:1;height:1px;background:#CBD5E1;"></div>
</div>
<div style="line-height:2;">
[https://id.wikipedia.org/wiki/ Bahasa Indonesia] ·
[https://ms.wikipedia.org/wiki/ Bahasa Melayu] ·
[https://nan.wikipedia.org/wiki/ 閩南語] ·
[https://bg.wikipedia.org/wiki/ Български] ·
[https://ca.wikipedia.org/wiki/ Català] ·
[https://cs.wikipedia.org/wiki/ Čeština] ·
[https://da.wikipedia.org/wiki/ Dansk] ·
[https://et.wikipedia.org/wiki/ Eesti] ·
[https://el.wikipedia.org/wiki/ Ελληνικά] ·
[https://eo.wikipedia.org/wiki/ Esperanto] ·
[https://eu.wikipedia.org/wiki/ Euskara] ·
[https://he.wikipedia.org/wiki/ עברית] ·
[https://hy.wikipedia.org/wiki/ Հայերեն] ·
[https://ko.wikipedia.org/wiki/ 한국어] ·
[https://hu.wikipedia.org/wiki/ Magyar] ·
[https://no.wikipedia.org/wiki/ Norsk] ·
[https://ro.wikipedia.org/wiki/ Română] ·
[https://simple.wikipedia.org/wiki/ Simple English] ·
[https://sk.wikipedia.org/wiki/ Slovenčina] ·
[https://sr.wikipedia.org/wiki/ Српски] ·
[https://sh.wikipedia.org/wiki/ Srpskohrvatski] ·
[https://fi.wikipedia.org/wiki/ Suomi] ·
[https://tr.wikipedia.org/wiki/ Türkçe] ·
[https://uz.wikipedia.org/wiki/ Oʻzbek]
</div>
</li>
<li style="margin-bottom:4px;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
<div style="flex:1;height:1px;background:#CBD5E1;"></div>
<div style="font-weight:bold;white-space:nowrap;">50,000+ articles</div>
<div style="flex:1;height:1px;background:#CBD5E1;"></div>
</div>
<div style="line-height:2;">
[https://ast.wikipedia.org/wiki/ Asturianu] ·
[https://az.wikipedia.org/wiki/ Azərbaycanca] ·
[https://bn.wikipedia.org/wiki/ বাংলা] ·
[https://bs.wikipedia.org/wiki/ Bosanski] ·
[https://ckb.wikipedia.org/wiki/ کوردی] ·
[https://fy.wikipedia.org/wiki/ Frysk] ·
[https://ga.wikipedia.org/wiki/ Gaeilge] ·
[https://gl.wikipedia.org/wiki/ Galego] ·
[https://hr.wikipedia.org/wiki/ Hrvatski] ·
[https://ka.wikipedia.org/wiki/ ქართული] ·
[https://ku.wikipedia.org/wiki/ Kurdî] ·
[https://lv.wikipedia.org/wiki/ Latviešu] ·
[https://lt.wikipedia.org/wiki/ Lietuvių] ·
[https://ml.wikipedia.org/wiki/ മലയാളം] ·
[https://mk.wikipedia.org/wiki/ Македонски] ·
[https://my.wikipedia.org/wiki/ မြန်မာဘာသာ] ·
[https://nn.wikipedia.org/wiki/ Norsk nynorsk] ·
[https://pa.wikipedia.org/wiki/ ਪੰਜਾਬੀ] ·
[https://sq.wikipedia.org/wiki/ Shqip] ·
[https://sl.wikipedia.org/wiki/ Slovenščina] ·
[https://th.wikipedia.org/wiki/ ไทย] ·
[https://te.wikipedia.org/wiki/ తెలుగు] ·
[https://ur.wikipedia.org/wiki/ اردو]
</div>
</li>
</ul>
</div>
</div>
<noinclude>[[Category:Starter Kit templates]][[Category:Main page templates]]</noinclude>
exir7rqcraea7skf3rre6cimfwg2mmq
User:UOzurumba (WMF)/Starter kit/Wikipedia's sister projects
2
174588
735787
2026-03-31T16:25:21Z
UOzurumba (WMF)
48890
Created by StarterKit tool
735787
wikitext
text/x-wiki
<div style="border:1px solid #CBD5E1;border-radius:4px;background:#ffffff;overflow:hidden;margin-bottom:16px;">
<div style="background:#F8FAFC;border-bottom:1px solid #CBD5E1;padding:8px 16px;font-weight:bold;">Wikipedia's sister projects</div>
<div style="padding:16px;">
Wikipedia is written by volunteer editors and hosted by the [https://wikimediafoundation.org/ Wikimedia Foundation], a non-profit organization that also hosts a range of other volunteer [https://wikimediafoundation.org/our-work/wikimedia-projects/ projects]:
<ul style="list-style:none;margin:8px 0 0 0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;">
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Commons-logo.svg|31px|link=https://commons.wikimedia.org/|alt=Commons logo]]<span>[https://commons.wikimedia.org/ Commons]<br/><small style="color:#555;">Free media repository</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:MediaWiki-2020-icon.svg|35px|link=https://www.mediawiki.org/|alt=MediaWiki logo]]<span>[https://www.mediawiki.org/ MediaWiki]<br/><small style="color:#555;">Wiki software development</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikimedia Community Logo.svg|35px|link=https://meta.wikimedia.org/|alt=Meta-Wiki logo]]<span>[https://meta.wikimedia.org/ Meta-Wiki]<br/><small style="color:#555;">Wikimedia project coordination</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikibooks-logo.svg|35px|link=https://www.wikibooks.org/|alt=Wikibooks logo]]<span>[https://www.wikibooks.org/ Wikibooks]<br/><small style="color:#555;">Free textbooks and manuals</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikidata-logo.svg|47px|link=https://www.wikidata.org/|alt=Wikidata logo]]<span>[https://www.wikidata.org/ Wikidata]<br/><small style="color:#555;">Free knowledge base</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikinews-logo.svg|51px|link=https://www.wikinews.org/|alt=Wikinews logo]]<span>[https://www.wikinews.org/ Wikinews]<br/><small style="color:#555;">Free-content news</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikiquote-logo.svg|35px|link=https://www.wikiquote.org/|alt=Wikiquote logo]]<span>[https://www.wikiquote.org/ Wikiquote]<br/><small style="color:#555;">Collection of quotations</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikisource-logo.svg|35px|link=https://www.wikisource.org/|alt=Wikisource logo]]<span>[https://www.wikisource.org/ Wikisource]<br/><small style="color:#555;">Free-content library</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikispecies-logo.svg|35px|link=https://species.wikimedia.org/|alt=Wikispecies logo]]<span>[https://species.wikimedia.org/ Wikispecies]<br/><small style="color:#555;">Directory of species</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikiversity logo 2017.svg|41px|link=https://www.wikiversity.org/|alt=Wikiversity logo]]<span>[https://www.wikiversity.org/ Wikiversity]<br/><small style="color:#555;">Free learning tools</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wikivoyage-Logo-v3-icon.svg|35px|link=https://www.wikivoyage.org/|alt=Wikivoyage logo]]<span>[https://www.wikivoyage.org/ Wikivoyage]<br/><small style="color:#555;">Free travel guide</small></span></li>
<li style="display:flex;align-items:center;gap:16px;padding:4px 0;">[[File:Wiktionary-logo-v2.svg|35px|link=https://www.wiktionary.org/|alt=Wiktionary logo]]<span>[https://www.wiktionary.org/ Wiktionary]<br/><small style="color:#555;">Dictionary and thesaurus</small></span></li>
</ul>
</div>
</div>
<noinclude>[[Category:Starter Kit templates]][[Category:Main page templates]]</noinclude>
6gmjkri3ke7d1hjrnav9a1xwnkp9dzr
User:UOzurumba (WMF)/Main Page
2
174589
735788
2026-03-31T16:25:24Z
UOzurumba (WMF)
48890
Updated Main Page via StarterKit tool
735788
wikitext
text/x-wiki
<div style="text-align: center; font-family: 'Linux Libertine', Georgia, Times, serif; margin: 1.5em 0;">
<span style="font-size: 2.3em; line-height: 1.2;">Welcome to Tyap Wikipedia</span><br/>
<span style="font-size: 1.1em; color: #54595d;">The free encyclopedia that anyone can edit</span><br/>
<span style="font-size: 0.95em; color: #72777d; margin-top: 0.5em; display: inline-block;">{{NUMBEROFACTIVEUSERS}} active editors • '''{{NUMBEROFARTICLES}}''' articles in Tyap</span>
</div>
{{Starter kit/Content categories}}
{{User:UOzurumba (WMF)/Starter kit/Wikipedia's sister projects}}
{{User:UOzurumba (WMF)/Starter kit/Wikipedia languages}}
__NOTOC__
c3yx34di6xwze2s76zqo64l4qwh4rwz
Ulivak
0
174590
735796
2026-03-31T19:50:16Z
Jackyja1ckyjacky
73355
Created page with "'''Ulivak''' is an town in [[BA-Li-she-ki|BA-Li-she-ki state]]. It was builded in March 1999.<ref>{{Cite web |last=John |first=Ugo |title=Ulivak Town |url=http://ugojohn.com/ulivak |access-date=unknown |website=Ulivak Town (Ugojohn)}}</ref>"
735796
wikitext
text/x-wiki
'''Ulivak''' is an town in [[BA-Li-she-ki|BA-Li-she-ki state]]. It was builded in March 1999.<ref>{{Cite web |last=John |first=Ugo |title=Ulivak Town |url=http://ugojohn.com/ulivak |access-date=unknown |website=Ulivak Town (Ugojohn)}}</ref>
h6262nk4bt6p8yx677vl50ojmwioqqs
Event:T421993-1
1728
174591
735813
2026-04-01T11:11:16Z
Daimona Eaytoy
37033
create
735813
wikitext
text/x-wiki
[[phab:T421993]]
buomarjti9r18x8ca6x01w4zwyix33c
Event:T421993-2
1728
174592
735814
2026-04-01T11:12:27Z
Daimona Eaytoy
37033
Created page with "[[phab:T421993]]"
735814
wikitext
text/x-wiki
[[phab:T421993]]
buomarjti9r18x8ca6x01w4zwyix33c