Vikisöz trwikiquote https://tr.wikiquote.org/wiki/Anasayfa MediaWiki 1.47.0-wmf.24 first-letter Ortam Özel Tartışma Kullanıcı Kullanıcı mesaj Vikisöz Vikisöz tartışma Dosya Dosya tartışma MediaWiki MediaWiki tartışma Şablon Şablon tartışma Yardım Yardım tartışma Kategori Kategori tartışma TimedText TimedText talk Modül Modül tartışma Event Event talk Süleyman Demirel 0 4 240648 235222 2026-10-16T22:12:58Z 2004onuralp 26941 Doğru mu? - https://www.facebook.com/rizetakip/videos/mesut-yilmaz-ve-kava%C4%9Fa-%C3%A7ikan-hamsis%C3%BCleyman-demirel-1991de-rize-meydan%C4%B1nda-bir-es/391889978860276/ 240648 wikitext text/x-wiki {{Biyografi}} '''Süleyman Sami Demirel''', Türk inşaat mühendisi ve siyasetçi. [[Türkiye|Türkiye Cumhuriyeti]]'nin 9. cumhurbaşkanı olup 1965-1993 yılları arasında da 7 farklı hükümette yaklaşık 12 yıllık bir süreyle başbakanlık yaptı. ==Sözleri== {{ABC}} === A === *Askerî cunta gelse ne yapacak, suçluları denize mi atacak? ** ''22 Ocak 1971 tarihli Millî Güvenlik Kurulu toplantısında.'' *Ağca hapishaneden nasıl kaçmıştır? Hapishaneler yol geçen hanına dönmüştür. Hapishanelerden pek çok kişi kaçmıştır. *Aksini diyenin alnını garışlarım! *Ağzını kapatacaksın! Ders verimi düşük oluyor. ** ''1980 öncesi mecliste, kendisine muhalif Ecevit'e tepkisi.'' * '''Açım diyene geber diyemezsiniz.''' === B === *1934 yılını hatırlıyorum. Ümit ve bereket olan yeşil, o yıl köyümüze uğramamıştı. Bir yılın ekmeği, yeşilin içinde gizliydi. Ama 1934 kuraklık ve kıtlık yılı oldu. Köylü, çoluk çocuk, genç ihtiyar, kadın kız topluca yağmur duasına çıktık. Ben de onların arasındaydım. Büyüklerin dualarını, çocukların ise bağrışmalarını hiç unutmuyorum.<br />İşte o gün bugün kuruyan başağın arkasından gidiyorum. Kuruyan başak, Türk köylüsünün ümididir. Tane, dolmadan kurumuşsa, solmuş demektir. Çaresizliğe terk edilişinin işaretidir. Medeniyetçilik mücadelesine beni iten, köylünün o kış çektiğidir. Ailemizde, eli tutan herkes çalışırdı. Evimizdeki işimizin dışında oyun oynamaya pek vakit bulamazdık. Okula giderken, elimize bir de odun alırdık. Çünkü okulda yakacak yoktu.<br />Okul yolunda beni çok yoran bir çantam vardı. Çantam neredeyse benim boyum kadardı. Bir elimde odun, bir elimde koca çanta, ayaklarımda da çok büyük ayakkabılarla uzun yol yürür, okula ulaşırdım.<ref>{{cite web | url = http://www.hurriyet.com.tr/demirelden-babasina-ataturk-rejiminde-siz-de-mebus-olabilirsiniz-29324734 | başlık = Demirel'den babasına: Atatürk rejiminde siz de mebus olabilirsiniz | erişimtarihi =2017-10-22 | yayımcı= Hürriyet | tarih = 19 Haziran 2015}}</ref> *Bak şu kiremitleri görüyor musun? Cumhuriyet bu kiremittir. Şu göleti görüyor musunuz? Cumhuriyet işte budur. Bakın şu baraja, Keban’dır, biz yaptık. Bu Cumhuriyet’tir. Şu fabrikaya bakarsınız, orada Cumhuriyet’i görürsünüz. Cumhuriyet, çimentodur, kiremittir, fabrikadır, yoldur, barajdır, kalkınmadır, refahtır.<ref name="Cumhuriyet">{{cite web |url=http://www.milliyet.com.tr/yazarlar/fikret-bila/cumhuriyet--benim-iste--2075504/ |başlık=Cumhuriyet benim işte! |erişimtarihi=23 Ekim 2017 |tarih=17 Haziran 2015 |yayımcı=Milliyet}}</ref> *Bana Türkiye’nin durumunu bir kelimeyle anlatın derseniz "'''iyidir'''" derim. İki kelimeyle anlatın derseniz "'''iyi değildir'''" derim.<ref>{{cite web | url = http://www.milliyet.com.tr/tezakir-i-cevdet/gundem/gundemyazardetay/20.11.2011/1464957/default.htm | başlık = Demirel siyaseti | erişimtarihi =2015-05-20 | yayımcı= Milliyet | tarih = 20 Kasım 2011}}</ref><ref>{{cite web | url = http://www.gazetevatan.com/muge-iplikci-633670-yazar-yazisi-iyiyiz-iyi/ | başlık = İyiyiz iyi | erişimtarihi =2015-05-20 | yayımcı= Gazete Vatan | tarih = 2 Mayıs 2014}}</ref> *'''Bana, "Sağcılar ve milliyetçiler cinayet işliyor." dedirtemezsiniz.''' ** ''1978 Maraş Katliamı olayları sonrası basına verdiği mülakattan.''<ref>Cumhuriyet gazetesi, 26 Aralık 1978 https://egazete.cumhuriyet.com.tr/oku/192/1978-12-26/0</ref> *Bugün sağ tedhişçi diye bir şey yoktur. Türkiye'de sol tedhişçi vardır, sağ tedhişçi diye bir şey yoktur. Adam öldüren yok yani.<ref>Abdi İpekçi ile görüşmesinden ''(22 Temmuz 1976, Milliyet)''</ref> *'''Ben altı kere gittiysem yedi kere geldim.''' ** ''"Sizi o bulunduğunuz yerden altı defa indirdiler, hâlâ orada oturmaya utanmıyor musunuz?" diye soran gazeteciye.'' *Ben bir gün evimde otururken Çankaya'ya çıkayım diyerek çıkmadım. * Basit ve anlaşılabilir ifade edemiyorsanız, yeteri kadar anlamamışsınız demektir. *Ben bir işe girersem adamı anasından doğduğuna pişman ederim. * '''Ben iyi yaşamak istemeyen bir halkı iyi yaşatamam ki!''' *Beşiktaş'ı niye sormuyorsun? ** ''Kendisine Fenerbahçe'yi mi, yoksa Galatasaray'ı mı tuttuğunu soran muhabire cevaben.'' *Binaenaleyh, öküzün altında buzağı aramanın manası yoktur. ** ''24 Ocak 1980'deki basın toplantısından.'' *Binaenaleyh Türkiye'nin altı çürüktür, Türkiye'nin altı çürüktür diye bırakıp gidecek değiliz, bununla yaşamasını öğreneceğiz. ** ''17 Ağustos depremi sabahı.'' * Binaenaleyh barışmasını bilmiyorsan, tartışmayacaksın. *Bulun 226'yı, düşürün hükümeti.<ref name="En popüler söz yığını"/> *Bulut buluttur, bulutun akı da buluttur garası da, binaaneleyh, üzerine gonuşmaya değmez. ** ''"Sayın Demirel, Yıldırım Akbulut için ne düşünüyorsunuz?" diye soran gazeteciye.'' * '''Bize plan değil, pilav lazım.''' ** ''70'li yıllarda ekonomik politikaların belirlenmesi sürecinde [[Cumhuriyet Halk Partisi|CHP]]'nin önerdiği planlı kalkınma önerisine cevaben.'' *Bu düzen böyle giderse elbet birileri çıkar, şapkayı giyer, kırata da biner. ** ''Cumhurbaşkanlığı görevi sonrası seçim zamanı gazeteciye verdiği cevap.'' *Ben 12 Eylül'le sandıkta hesaplaştım. ** ''12 Eylül yargılamasında müdahil olup olmayacağı konusunda.'' *Biz özel televizyonlara '' "hür olun" '' dedik. '' "Çıplak olun" '' demedik ki!<ref>http://www.cumhuriyetarsivi.com/katalog/192/sayfa/1993/1/13/5.xhtml</ref> ** ''Özel televizyonlar ve yayınlarının müstehcenliği tartışmaları olduğu sırada.'' *Bunların gidişi Allende gidişidir, sonları nasıl olur bilmem.<ref>[https://web.archive.org/web/20230526141034/https://1.bp.blogspot.com/-w_8AE02c8WI/X4BW8XmOjOI/AAAAAAAAxLc/BPyY0DOmSeESmOqsJPcQOc5s1Q7IXsOTwCLcBGAsYHQ/s838/all1.bmp 20 Mart 1979 tarihli ''Milliyet'' gazetesi]</ref> ** ''1979 yılında Başbakan [[Bülent Ecevit]]'i öldürülen Şili Devlet Başkanı [[Salvador Allende]]'ye benzetir.'' *Bu takdir-i ilahidir. Herkes söylediğimi iyi dinlesin. Bu, Cenab-ı Allah'ın takdiridir. Biz Müslüman bir ülkeyiz ve İslam inançlarına sahip bir milletiz. Doğanın gücü dediğimiz afetler ortaya konduğu zaman bunun karşısında insanoğlunun ne kadar sıkıntıya düştüğünü, ne kadar acze düştüğünü ilk defa görüyor değiliz. Çünkü bu bir muhteşem güçtür; ölçülmesi, biçilmesi mümkün olmayan ve bizim dileyeceğimiz şey bu gibi hadiseler karşısında beterinden ve tekrarından Cenab-ı Allah'ın milletimizi, memleketimizi korumasıdır. Hiç bunun eleştirilecek yeri yoktur.<ref>[https://www.youtube.com/shorts/zZr-CCaYtAQ Süleyman Demirel - Bu Deprem Cenabı Allah'ın Taktiridir. (Gölcük Depremi /1999)]</ref> ** ''17 Ağustos depremi için yaptığı açıklama.'' * '''Boş tencerenin yıkamayacağı iktidar yoktur'''. === C === *CHP, tanklar dolusu motorin ve fuel-oil devretti de biz bunları içtik mi?<ref>[https://www.youtube.com/watch?v=hivySFo_4ls Süleyman Demirel: Benzin vardı da biz mi içtik?]</ref> * '''[[Cami]]ye siyaset girerse ibadet kalmaz, mahkemeye [[siyaset]] girerse [[adalet]] kalmaz! ''' === Ç === *'''Çorum'u bırakın, Fatsa'ya bakın.''' ** ''Çorum olayları hakkında düşüncülerini soran gazeteciye cevabı.'' *Çaya yapılan zam değildir. Kalite ayarlaması yapıldı. Çayın kalitesi yükseltildi. ** ''Çaya yapılan zammı soran muhabirlere.'' === D === *Darbe Komisyonu'na ben ifade veriyor değilim. Eğer Darbe Komisyonu ifade almak istediğini söyleseydi ben kabul etmezdim onu. Ben devletin işlerini zorlaştırmam, kolaylaştırırım. Bilgi istiyorsanız verdik bilgi ama o kadar çok bilgi alındı ki sağdan soldan bunun içerisinden nasıl çıkılacağını doğrusu ben de merak ediyorum. Ama söylüyorum inşallah Darbe Komisyonu bu görevini bir tahkikat komisyonu haline getirmez.<ref name="Özal"/> *Devlet seçim sonuçlarına göre gereken tedbirleri alır. * ''“Daha fazla daha iyidir”'' diye kendinizi kandırmayın. *'''Devlet bazen rutinin dışına çıkabilir.''' ** ''Kasım 1996 [[Susurluk Kazası|Susurluk]] skandalı sonrası'' * '''Derin devlet, normal devletin raydan çıkmış halidir.''' ** ''Derin devletin ne olduğunu soran bir muhabire cevaben.'' *[[Demokrasi]]lerde çareler tükenmez. *'''Dün dündür, bugün bugündür.'''<ref name="En popüler söz yığını"/> *DYP'yi ben kurdurdum. *'''Dünkü güneşle bugünkü çamaşır kurutulmaz.''' *Dört kaz teslim etsen, akşama üçünü kaybedip gelir. ** ''1980 öncesinde [[Bülent Ecevit]]'e.'' * Dünyanın hiçbir ülkesinde zimmetinde 1200 ölü, %70 enflasyon, itibarsızlık, zulüm, işkence, adaletsiz ve merhametsiz partizanlık bulunan böyle bir hükûmet, bir gün dahi ayakta duramaz. Hırsı boyunu aşmış bir kadro, idareyi gasbetti. ** ''Bülent Ecevit hükûmetine, 11 Şubat 1979'' === E === * '''Efendim ben ne yapayım? '' "Askerler yapmadı, başaramadı." '' demek fevkalade dalalet olur.''' : ''3 Ağustos 1980 günü yapılan sıkıyönetim koordinasyon toplantısında askerlerin anarşi ve terörle mücadelesini takdir ederken'' *Elektriğin komünisti olur mu? *Enkaz devraldık.<ref name="En popüler söz yığını"/> *Esasen [[Suriye]], Türkiye'ye karşı açık bir husumet politikası izlemektedir. PKK terör örgütüne aktif destek sağlamayı sürdürmektedir. '''Tüm uyarılarımıza rağmen hasmane tutumundan vazgeçmeyen Suriye'ye karşı mukabelede bulunma hakkımızı saklı tuttuğumuzu, sabrımızın taşmak üzere olduğunu bir kere daha dünyaya ilan ediyorum.''' ** ''1 Ekim 1998 TBMM Yasama Yılı Açış Konuşması'ndan.'' *Eylemciler direktifi Ecevit'ten alıyor. Hükûmetin başı bir avuç para babasının hükûmeti tehdit ettiğini açıkça ilan ederek bunların hakkından gelinmesini istemiştir. Bu talebi 2 gün sonra yerine getirilmiştir. ** ''24 Temmuz 1979 günü İstanbul'da 100'e yakın eylemcinin 7 iş yerini basıp bombalaması hakkında'' === F === *Fırat'ın kenarındaki bir kuzudan ben sorumluyum. *Fiyatlar günden güne artıyorsa memlekette pahalılık var demektir. === G === * '''Galibiyetin sahibi çoktur, mağlubiyetin sahibi yoktur. Yenilgi yetimdir.''' *'''GAP'ı kimseye gap diye gaptırmam.''' *Geçmişi kötülemek suretiyle hiç kimse kendini parlatamaz. Herkes kendi icraatını ortaya koymalıdır. * Geçmiş pişmanlık, gelecek endişedir. Huzur ise; sadece şu anda, bu gündedir. *Goalisyon hökümetimiz hayırlı uğurlu olsun. ** ''1991 genel seçimleri sonrası DYP-SHP koalisyon hükümetinin kurulduğu gün.'' *Güniz Sokak'ta Nazmiye ile tavuk besleyecek değiliz. *Günah benden gitti! ** ''1990'larda PKK'nın eylemlerinin arttığı sırada.'' === H === * '''Hiç silah satan [[barış]] ister mi, ilaç satan [[sağlık]] ister mi, din satan [[Bilim|ilim]] ister mi, hırsız olan [[hukuk]] ister mi?''' *Herkes benim gibi, ''"Dün dündür, bugün bugündür."'' deyip işin içinden çıkamaz! ** ''Cumhurbaşkanlığının son basın toplantısında.'' *Hükûmet; ayakta durdukça anarşiyi körükler, ona cesaret verir. Ecevit; hile, entrika ve desise ile ele geçirdiği bugünkü ayıplı hükûmetin memleket meseleleri altında ezilmesinden dolayı feryat ediyor. ** ''2 Temmuz 1978'' *Hükûmet, günahlarının içinde boğulup gidecek. 14 ay içinde meydana gelen kan denizinin başsorumlusu hükûmettir. Başbakan silahların gölgesine sığınmıştır. **''3 Mart 1979'' * Hiçbir suyun derinliğini iki ayağınızla birden yoklamayın. * Her tohum kendi toprağında yeşerir, tohum çiçeğini, çiçek meyvesini göremez. * Hamsi kavağa çıkar mı? Hamsi kavağa çıkarsa onlar iktidar olur. ** ''20 Ekim 1991 genel seçimlerinden önce düzenlediği bir mitingte yaptığı konuşmadan.'' * '''[[Halk]] yaş sebze gibidir, günlük yaşar.''' * Huzurlu bir yaşam için dinleten değil dinleyen, yargılayan değil anlayan, eleştiren değil hoşgören, kavga eden değil affeden olun. * Hakiki dost iyi günde davetle, kötü günde kendiliğinden gelir. *Hükûmetin başı. ** ''Kendi partisinden 11 milletvekili transfer ederek hükûmeti kuran [[Bülent Ecevit]]'ten bahsederken, başbakan demek yerine.'' * '''Hayat maçını kaybettiren golleri en çok '' “Kendinizi en güçlü hissettiğiniz anlarda” '' yiyebileceğinizi aklınızdan çıkarmayın.''' === İ === *İcabı olup olmadığı tartışılabilir. Ama icabı varsa [[feminizm]] fevkalade güzel bir şeydir. ** ''Elele dergisine verdiği mülakatta.'' *İşiniz vardı da biz mi aldık? ** ''12 Temmuz 1969'da iş isteyenlere söylediği.'' *İşsizlikten kurtulmak istiyor musunuz? Takılın peşimize. ** ''1991 genel seçimleri öncesi miting konuşmalarından.'' *İşte ben bu odada kardeşlerimle yaşadım. Elektrik yoktu. Gaz lambasıyla okur-yazardık. Köy okulunu bitirdim. Ortaokul yoktu. Ortaokula gitmek için her sabah kilometrelerce yürür, kasabaya giderdik. Sonra Afyon Lisesi. Eğer bana Cumhuriyet nedir, diye sorarsınız. Size cevabım şudur: '''Cumhuriyet benim işte! İslamköy’den çıkmış bir köylü çocuğunu cumhurbaşkanı yapan, Cumhuriyet’tir. Cumhuriyet budur. Bunu Büyük Atatürk’e borçluyuz.'''<ref name="Cumhuriyet"/> === K === *Kendim için bir şey istiyorsam namerdim.<ref name="En popüler söz yığını"/> * Kederde de mutlulukta da '' “Bu da geçer” '' demeyi unutmayın. * Kaybettiklerinizin bazen kazancınız da olabileceğini unutmayın. *Kırk günde kabak yetişmez. ** ''1978'de CHP'nin 40 günde Türkçe bilmeyen öğretmenleri alıp öğretmen yapması için demiştir.'' *'''Kim ödeyecek 350 milyar lira zararı? Ben öderim diyen bir babayiğit çıksın göreyim, devlet öder diyen çıksın göreyim. Nereden öder devlet 350 milyar lira zararı?''' ** ''24 Ocak 1980 tarihli basın toplantısından.'' *Kayserililer benden daha da uyanık. ** ''Kayseri mitingi sonrası.'' *Köprülerin altından daha çok su akar, dünyanın sonu değil. *Kan döken insanlar '' "biz kan dökmekten vazgeçtik" '' derlerse, '' "iyi yaptınız, alın size bir mükâfat verelim" '' denmesi mümkün değil. Kan döken insanlara '' "aman vazgeçmeyin, kan dökmeye devam edin" '' demek de mümkün değil. Kan döken insanlar bundan vazgeçerlerse, '' "bu iyi olmadı" '' demek de mümkün değil.<ref>{{web kaynağı|url = http://www.milliyet.com.tr/demirel-in-unutulmayan-sozleri-gundem-2075042/ |başlık= Demirel'in unutulmayan sözleri |yayıncı= Milliyet gazetesi |erişimtarihi= 15 Eylül 2015}}</ref> * '''Kim ne veriyorsa, 15 lira fazlasını veriyorum!''' ** ''Ekim 1991 genel seçimleri zamanı kampanya döneminden.'' * Kontrgerilla tartışması kadar, [[Türkiye]]'de havanda su dövülen bir konu yoktur. Deniyor ki, araştıralım. O zaman her şeyi araştıralım, yarın güneş doğacak mı diye araştıralım?! ** ''Tarih: 24 Şubat 1993'' === M === * '''Meseleleri mesele etmezseniz, ortada mesele kalmaz.''' *Mizah bir yumruktur, ne zaman kime vuracağı belli olmaz. *Memlekette gaz vardır. ** ''"Gaz sıkıntısı için hükümet ne gibi önlemler alıyor?" diye soran gazeteciye.'' *'''Memleket meseleleri bir parkta oturarak halledilseydi; çok büyük bir park yaptırır, hep beraber içinde otururduk.''' * [[Millî İstihbarat Teşkilatı|MİT]] gizli saklı işler yapan bir teşkilat değildir. * [[Mutluluk]], küçük şeyleri büyük fırsatlara çevirebilme becerisidir. * '''Mümkünü namümkün, namümkünü mümkün yapmak namümkündür.''' === N === *Neden çifte vatandaşlık verecekmişiz? Kendilerini Türk hissediyorlarsa gelip Türkiye'ye yerleşsinler. ** ''Tarihçi [[Kemal Karpat]]'ın 1969'da Başbakan Demirel'den yurt dışındaki Türkler için "Çifte Vatandaşlık Kanunu" çıkarılmasını teklifi üzerine verdiği cevabı. (26 Nisan 2009 tarihli Zaman gazetesinin 18. sayfasındaki haberi.)'' *Nerede kalmıştık? ** ''1987 - Siyasi yasaklı döneminin bitmesinden sonra katıldığı ve genel başkan seçildiği DYP kongresinde, kürsüdeki ilk sözü.'' * Ya neresini sıksaydım kardeşim? ** ''[[Birleşik Krallık]] ile ilişkilerin gergin olduğu bir dönemde yapılan bir görüşmede, [[Bülent Ecevit]]'in elini sıkmasının doğruluğunu kendisine soran gazetecilere cevaben.'' *'''Ne yabancı sermayesinden bahsediyorsunuz? Kasaplığı Türkiye'de vatandaşın elinden almaya kalkmışsınız, ne sermayesi gelir Türkiye'ye? Çırpınır durursunuz.''' ** ''24 Ocak 1980 tarihli basın toplantısından.'' *Ne zammı yapmışız ki? Zammın bizimle ne alakası var? 19 günlük hükümet ne zammı yapsın? Yani eğer zammın hoş bir şey olmadığını, kimseyi sevindirmediğini biz bilmiyor muyuz? Öyleyse popülaritemizi kaybetmek için durup durduğumuz yerde zam yapacak kadar bizi akılsız mı sanıyorsunuz? Zam biz yapmadık. Zam iki ay evvel yapılacak şekilde konmuş duruyor, seçim geçsin, yapmayalım demişler, bizim önümüze geldi. Biz de düşündük taşındık, baktık, çektik, yapacak başka bir şey yok. Biz bir şey yapmadık, biz bulduk bunları, üstünde oturalım mı oturmayalım mı diye düşündük baktık oturamadık üstünde, civciv çıkacak çünkü.<ref>[https://www.youtube.com/watch?v=vRae1BI-N-4 Demirel-1991 "Zammı kucağımda Buldum"]</ref> ** ''1991 - Bir basın mensubunun "Bu zamlardan sonra halk size hâlâ Baba diyecek mi?" sorusuna yanıtı.'' *Niye? Biz mi öldürdük? ** ''Başbakanlık kapısında bekleyen bir atı ölmüş ama iki at parası isteyen yaşlı adama verdiği cevap.'' === O === *Olaylar fevkalade. ** ''13 Mart 1995 Gazi Olayları sırasında basına yaptığı açıklama.'' *11 Eylül 1980 günü, Sıkıyönetim'e rağmen ülkenin her yerinde oluk oluk kan akıyordu. Nasıl oldu da 24 saat sonra her tarafta silahlar sustu ve her yer sütliman oldu? ** ''12 Eylül 1984.'' *11 Eylül 1980'de Milli İstihbarat Teşkilatı ülkenin Başbakanı'na Angara'da olan biteni anlatmak yerine, Angola'daki olaylar hakkında rapor veriyordu. ** ''12 Eylül 1984.'' *Orası üniversite, oranın kuralları var. Danıştay, Anayasa Mahkemesi karar vermiş. İlla başı bağlı okumak istiyorsan, başı bağlı olarak okunabilen yerler var, oraya git. Arabistan'da falan öyle yerler vardır, oraya gidin, orada okuyun. Türkiye laiklikten vazgeçemez. Herkes aklını başına toplasın. Cumhuriyetin beşinci neslini yetiştirmiştir cumhuriyet ve bu nesil cumhuriyete sahip çıkmaktadır. '''Türban özgürlük falan değildir; bu, gericiliktir.''' ** ''2006.'' *'''Ordunuzu tahrip etmek istiyorsanız onu [[siyaset|siyasete]] sokun, yapılacak en kestirme yol budur.'''<ref>[http://yillarinogrettigi.ntvmsnbc.com/default.aspx?p=15&i=37 Ordunuzu tahrip etmek istiyorsanız onu siyasete sokun, yapılacak en kestirme yol budur.]</ref> === P === *Parazit yapıyor! ** ''Zam isteyen sendika liderlerine.'' === S === *[[Said Nursî|Said Nursi]] büyük âlimdir, "Büyük âlim değildir" diyenin alnını karışlarım. ** ''1999 yılında Kocatepe'de yapılan [[Said Nursi]] mevlidine gönderdiği mesaj.'' *Su mu daha değerlidir yoksa petrol mü? Tabii ki su daha değerlidir. Çünkü petrol içilmez ama su içilir. * Sabır öfkeden, nezaket nefretten iyidir. *Sana ne? Tasası sana mı düştü? Sen mi talipsin? Sana vermemi ister misin? Kime vereceksem vereceğim, verince görürsünüz! Bu böyle olmaz, biraz sabretmesini öğrenin! ** ''28 Şubat sürecinde hükümeti kurma görevini kime vereceği konusunda soru soran bir muhabiri paylarken.'' *'''[[Siyaset]] bir meslek değildir, bir ilim de değildir. Nedir derseniz; siyasettir derim.''' *Siyasi hakları vermek görevimiz de, Türk Silahlı Kuvvetleri'ni rencide ettirmemek görevimiz değil mi? ** ''[[Celâl Bayar]] ve arkadaşlarının affedilmesi konusunda; ordunun bakışına karşı AP Meclis Grubunda söylediği söz.'' * Sinir ve hiddetin yakışmadığı bazı makamlar vardır; [[Cumhurbaşkanı|Cumhurbaşkanlığı]] da o makamların başında gelir. ** ''Son başbakanlığı döneminde (1991-1993); yaşadıkları anlaşmazlıklar sonrası, o zamanın Cumhurbaşkanı [[Turgut Özal]]'ı ima ederek. '' * '''[[Siyaset|Siyasette]] 24 saat, çok uzun bir süredir.''' *Solculuk yokken ülke rahattı. Solculuk çıktıktan sonra ülkenin rahatı bozulmuştur.<ref>Cumhuriyet gazetesi, 23 Mayıs 1978</ref> ** ''Yıl: 1978'' === Ş === *Şapkamı alır giderim.<ref name="En popüler söz yığını">{{cite web |url=http://arama.hurriyet.com.tr/arsivnews.aspx?id=-105508 |başlık=En popüler söz yığını |erişimtarihi=16 Ekim 2010 |tarih=3 Ekim 1999 |yayımcı= Hürriyet}}</ref> === T === *Tespih çeken elle, tetik çeken el bir olmaz.<ref name="En popüler söz yığını"/> * [[Türkiye]]'nin birinci sorunudur enflasyon. Hakikaten bugün, enflasyon dediğiniz halk günlük yaşar, halkın birinci sorunu geçim sıkıntısıdır. Esasen enflasyon, devletleri yıkan bir olaydır. Milletleri içinden bozan bir olaydır. Enflasyon sadece pahalılık olayı da değildir. [[Ahlak]]ı bozar. Borcu olan borcunu ödemez, alacağı olan alacağını alamaz. Hırsızlıktan, soygundan, fuhuşa kadar hemen hemen bütün yolları açar. Toplumun içini bozan bir olaydır. Onun içindir ki Batılılar, enflasyona ''"bir numaralı halk düşmanı"'' derler. ''"Tek kollu canavar"'' derler. Batı enflasyondan fevkalade çekinir. ** ''11 Ekim 1991.'' * '''[[Türkiye]] yönetilemez, ancak idare edilir.''' *[[Türkiye]] 70 cent'e muhtaç olduğu devirde, hacılarımıza 70 milyon dolar ayırdık. * '''[[Türkiye]]'de [[Koalisyon hükûmeti|koalisyon]], seçimden önce kurulur.''' *Turbun büyüğü heybede. *Turgut Özal'ın başkaları tarafından öldürüldüğü iddialarının hiçbirisine katılmıyorum. Ben katılmam, eğer öyle bir durum varsa bulur çıkarırlar. 19 sene bulunup çıkarılmamış şimdi dahi bulunup çıkarılması geç değildir. Artık o görev adaletindir, başkasının değildir.<ref name="Özal">[http://www.ntvmsnbc.com/id/25401057/ Demirel: Özal zehirlenmedi, tüm laflar safsata], ntvmsnbc.com</ref> *Türk Silahlı Kuvvetleri'ni her gün idareyi devralmaya davet edenlere şunu sorarız: O zaman yurt savunmasını kim yapacaktır? '''Türk Silahlı Kuvvetleri'nin rejimin ve cumhuriyetin bekçiliği görevini bırakıp idareyi ele alması halinde, bizatihi korumakla mükellef oldukları rejim, cumhuriyet ne hale gelir?!''' ** ''12 Mart'a giden süreçte, 22 Ekim 1970 tarihli bir basın toplantısından.'' === Ü === *Üs yok tesis var.<ref name="En popüler söz yığını"/> *Üzülmeyin çocuklar, üzülmeyin. Ben bir işe girersem adamı anasından doğduğuna pişman ederim. ** ''Görev süresinin dolmak üzere olduğu dönemde, ATO Başkanı Sinan Aygün'e hitaben.'' === V === *Vaa mı bunun başka türlü izah tarzı? *Vatana millete hayırlı uğurlu ossun. *Verdimse ben verdim, ne olmuş?! ** ''İlksan ile ilgili Kemal Ilıcak'a verilen paralarla ilgili yolsuzluk haberi üzerine suç üstü yakalanınca demiştir.'' === Y === * 50 yılı aşkın kamu hizmetim, 35 yıllık [[siyaset]] hayatım, 7 yıllık Cumhurbaşkanlığım boyunca büyük [[Türkiye]] hedefi, demokrasinin ve anayasal kurumların güçlenmesi, demokratik kuralların işlemesi için mücadele ettim. ** ''Cumhurbaşkanlığının son basın toplantısında.'' *Yasaksız Türkiye. ** ''1982 Anayasası'yla siyasetten yasaklı olduğu dönemde kullandığı slogan.'' *Yazın biz [[Bulgaristan]]'dan elektrik alıyoruz. Kışın [[Bulgaristan]] bize elektrik veriyor. * [[Yağmur]] yağarken '' "ben ıslanmam" '' diyemezsiniz. * Yıllarınızı nasıl geçirdiğiniz; o yılların içine ne kadar çok hatırlanabilir ve güzel an ve anı sığdırdığınız, sizin kaç yıl yaşadığınızdan çok daha önemli ayrıntılardır. *Yapamazsın onu, oraya girmeyin hiç! Bak bir şey söyleyeyim; Çanakkale'ye giden 250 bin kişinin de anası-babası vardı! ** ''[[Abdullah Öcalan]]'ın idama mahkum edildiği dönemde kendisinden yardım isteyen Şehit Aileleri Derneği üyelerinden birinin '' "Biz devletimize güvenmeseydik, çocuklarımızı askere göndermezdik." '' sözüne cevaben.'' *28 Şubat'ta benim yaptığım her şey anayasaldır, kanunlara uygundur ve Türkiye Cumhuriyeti'nin temel esaslarını korumaya yöneliktir. Ben görevimi yaptım. Zaten aradan şu kadar zaman geçmiş bu kadar sene geçtikten sonra neyi arıyorsunuz...<ref name="Özal"/> *Yollar yürümekle aşınmaz.<ref name="En popüler söz yığını"/> ** ''12 Mart 1971 öncesi sol örgütlerin yürüyüşleri ile ilgili söylemiştir.'' *Yahya'yı ben kulağından tutup mahkemeye verdim. ** ''Türkiye'nin ilk hayali ihracatını gerçekleştiren yeğeni Yahya Demirel için, cumhurbaşkanlığının son basın toplantısında böyle söylemişti. Doğrusu yolsuzluğu ortaya çıkaran Ticaret Bakanlığı müsteşarı Şerafettin Durugönül'ü görevden almıştı.'' * '''Yenilmiş kul hakkını ne [[Mekke]] temizler ne de tekke.''' * Yetmiş iki milletin önünde Kel Osman'ın apalak ikizleri gibi depişmenin manası yoktur. ** ''1992 yılında Demirel başbakanken düzenlenen Dünya Ekonomik Forumu'na (Davos) Türkiye düzeyinden temsil katılımı konusunda o dönemin Cumhurbaşkanı [[Turgut Özal]] ile yaşadığı şiddetli anlaşmazlık sonrası.'' ==Hakkında söylenenler== * Yok, yok, böylesi görülmemiştir... : Böylesi, Türkiye Cumhuriyetinde ilk kez görülüyor, dünya demokrasi tarihinde de böylesine Başbakanlara rastlandığını ve rastlanacağını sanmıyorum...<ref>Uğur Mumcu, Cumhuriyet, 12 Mart 1980</ref> [[Uğur Mumcu]] * Ecevit hükümeti döneminde iki yıl içinde siyasal nedenlerle öldürülenlerin sayısı 2245'dir. Yetmiş günlük Demirel hükümetinde siyasal nedenlerle öldürülenlerin sayısı şimdiden 504'ü bulmuştur! : Bu sayılar gösteriyor ki, terör azalmıyor, çoğalıyor.<ref>Uğur Mumcu, Cumhuriyet, 1 Şubat 1980</ref> [[Uğur Mumcu]] * Demirel'in yakın çevresi, bir zamanlar Demirel'e ağız dolusu sövenlerle doludur. Demirel'e en çok söven Dr. Bilgiç, bu hüneri nedeniyle Demirel'in en yakınında yer almıştır. Bunların "millî ve manevi değerler" anlayışı, bu açıdan oldukça büyük gelişim göstermiştir.<ref>Uğur Mumcu, Cumhuriyet, 20 Ekim 1979</ref> [[Uğur Mumcu]] * Ve Demirel, evlerinde çoluklarıyla çocuklarıyla boğazlanan Kahramanmaraş halkının kanlı cesetlerine bakarak konuşuyor: : ''— Bana, "Sağcılar ve milliyetçiler cinayet işliyor." dedirtemezsiniz.'' : Demirel'in insanlığını anlamak için bu sözler yeter. Böylesi bir politikacıya bugüne dek ne dünya tarihinde rastlanmıştır ne de Türkiye'de! Demek iktidar hırsı insanların gözlerini ve vicdanlarını böyle karartabiliyor.<ref name="ReferenceA">Uğur Mumcu, Cumhuriyet, 26 Aralık 1978</ref> [[Uğur Mumcu]] * ''— Bana sağcılar ve milliyetçiler cinayet işliyor dedirtemezsiniz...'' : Sana, ''«Yahya Demirel devleti dolandırmıştır»'' da dedirtmek mümkün değildir, biliriz! Tabii, şu kanlı katilleri, şu alçak sürüsünü, şu namussuz alayını suçlamak için ağzından bir tek söz çıkmayacak.<ref name="ReferenceA"/> [[Uğur Mumcu]] * Evet ne olacak sonu? Ben merak ediyorum kendi hesabıma... Menderes gibi idam sehpalarını mı boylayacak? Yoksa, ''«bıktım bu işlerden»'' deyip, rahat köşesine mi çekilecek? Ne yapacak? Ne edecek? İş adamı mı olacak? Amerikan firması komisyonculuğuna mı dönecek?<ref>Uğur Mumcu, Cumhuriyet, 17 Kasım 1977</ref> [[Uğur Mumcu]] * ''"[[Bülent Ecevit|Ecevit]] isterse görüşürüm."'' diyen Demirel, 11 Şubat (1979) günü, ''"Dünyanın hiçbir ülkesinde zimmetinde 1200 ölü, %70 enflasyon, itibarsızlık, zulüm, işkence, adaletsiz ve merhametsiz partizanlık bulunan böyle bir hükûmet, bir gün dahi ayakta duramaz. Hırsı boyunu aşmış bir kadro, idareyi gasbetti."'' şeklinde beyanat veriyordu. Bir taraftan sırf cumhurbaşkanı istiyor diye ''"Ecevit isterse görüşürüm."'' diyeceksin, diğer taraftan hemen arkasından konuşacağın kişiyi böylesine çirkin kelimelerle suçlayacaksın. Elbette böyle bir durumda diyalog kurulamaz.<ref name="ReferenceB">Kenan Evren, Kenan Evren'in Anıları 1, 1990</ref> [[Kenan Evren]] * ... 24 Temmuz (1979) günü İstanbul'da 100'e yakın militan yedi iş yerini bastı ve bombaladı. Demirel bu fırsatı kaçırır mı? Hemen ertesi gün, ''"Eylemciler direktifi Ecevit'ten alıyor. Hükûmetin başı (Bir türlü başbakan diyemedi.), bir avuç para babasının hükûmeti tehdit ettiğini açıkça ilan ederek bunların hakkından gelinmesini istemiştir. Bu talebi iki gün sonra yerine getirilmiştir."'' diyerek Ecevit'i de teröristlerin başı yaptı, çıktı işin içinden. Bunu sade bir vatandaş söylese ceza kanunlarımıza göre ağır bir suç işlemiş olur. Ama parlamenter söylerse suç olmuyor.<ref name="ReferenceB"/> [[Kenan Evren]] *İnsanda insaf, izan olmazsa işte böyle söyler, ''"Dün dündür, bugün bugündür."'' dediği gibi.<ref name="ReferenceB"/> [[Kenan Evren]] : ''Demirel'in, [[12 Eylül Darbesi|12 Eylül]]'den önce askerlerin anarşi ve terörle mücadelesini överken 12 Eylül'den sonra, "İdareye el koymaya kararlı oldukları için bilerek anarşinin üzerine gitmediler." sözü hakkında'' * Binlerce kişinin öldürüldüğü, her gün 20 vatandaşın katledildiği, arkalarından birçok yakınlarının gözyaşı döktüğü günler ne çabuk unutuldu. Kan ve gözyaşı dökülmesini bir türlü önleyemeyen idareciler başkaları mıydı? Evet, sen döktürmedin, sen de gözyaşı dökmedin ama kan dökenlere mâni olacak tedbirleri alamadın, aldırtamadın. "Ben önleyecek değilim ya!" diyemezsin. Zira önleyecek tedbirleri aldırtacak makamda idin.<ref>Kenan Evren, Kenan Evren'in Anıları 5, 1991</ref> [[Kenan Evren]] *Sayın [[Mesut Yılmaz|hükümet]] 'enayi miyim?' diyor, 'zam yapacağım' diyor 'seçimden önce'. Yani seçimden sonra 'kazığı getiriyorum' diyor. Acı ilacı getiriyor, dayıyor. Süleyman Demirel? Dayayacak. Esas ustası.<ref>[https://twitter.com/siyasiposting/status/1247993052645462020 "süleyman demirel, dayayacak. esas ustası."]</ref> [[Doğu Perinçek]] (1991 Liderler Açık Oturumu) == Kaynakça == {{Kaynakça}} ==Dış bağlantılar== {{Vikiler |commons = Category:Süleyman Demirel |wikispecies = |wikt = |b = |s = |w = |n = Kategori:Süleyman Demirel |m = |}} [[Kategori:Kişiler-S]] [[Kategori:Türkiye başbakanları]] [[Kategori:Türkiye cumhurbaşkanları]] [[Kategori:1924 doğumlular]] [[Kategori:2015 yılında ölenler]] 3i6mk4wgkmzc7ic9vjfqqre3wkgn1b8 Abdülhakîm Arvâsî 0 21476 240649 187162 2026-10-17T07:49:51Z Esvc.emre 20239 240649 wikitext text/x-wiki {{Kaynaksız}} {{Biyografi |kişi_adı=Abdülhakîm Arvâsî Üçışık |resim_adı= |resim_başlığı= |doğum_tarihi=1860 |doğum_yeri=Başkale, Van, Osmanlı İmparatorluğu |ölüm_tarihi=27 Kasım 1943 |ölüm_yeri=Ankara, Türkiye }} '''Abdülhakîm Arvâsî Üçışık''' (1860, Başkale, Van - 1943, Ankara), Türk İslam âlimidir. ==Sözleri== *Cemiyetteki ruh hastalıklarının sebebi, iman eksikliğidir. *Riya olmasın diye cemaatten kaçanlar ayrı bir riya içindedirler. *Haramlardan korkan zahiddir. Şüpheliden korkan ise velidir. *Tek vakit namazımı kaçırmaktansa, bin kere ölmeyi tercih ederim. *Namaz, aman namaz, nerede ve ne şart altında olursa olsun mutlaka namaz kılın. *En büyük edep, ilahi hududu muhafazadır, gözetmektir. *Allahü Teâlâ bir kuluna iman vermişse ona daha ne vermemiştir. İman vermemişse ona daha ne vermiştir! *Bizim meclisimizde bulunanlar, sükut içinde otursalar ve sükuttan başka bir şey görmeseler bile, din bahsinde âlim geçinenlerin hatalarını keşfederler, bir bir çıkarırlar. *Kur'an-ı Kerim şifadır. Fakat şifa, suyun geldiği boruya tâbidir. Pis borudan şifa gelmez. *Gerçek keramet, kerametin gizlenmesidir. Bunun dışında görünenler, velinin irade ve ihtiyarı ile değildir. İlahi hikmet öyle gerektiriyor demektir. *Allahü Teâlâ sırrını eminine verir. Bilen söylemez, söyleyen bilmez. *Ahmaklık, hatada ısrar etmektir. *Kur'an-ı Kerim'den ve Resul aleyhisselamın hadis-i şeriflerinden sonra en kıymetli kitap, İmam-ı Rabbani hazretlerinin Mektubat kitabıdır. Hanefi mezhebinde en mükemmel ve en kıymetli fıkıh kitabı, İbni Abidin'in Dürrül-Muhtar haşiyesidir. Şafii’de Tuhfet-ül-Muhtac kitabıdır. *Din bilgileri, dünyada ve ahirette, huzuru, saadeti kazandıran bilgilerdir. *Allahü Teâlâ dilediğini yapar. İster sebepli ister sebepsiz, dilediği gibi azap veya lütfeder. Güzel ve doğru Onun dilediğidir. *Allahü Teâlâ bize rahmetiyle muamele etsin. Adaletiyle muamele ederse yanarız. *İlim cehli izale eder, yok eder, ahmaklığı değil. *Allahü Teâlâ, her şeyi bir sebep altında yaratmaktadır. Bu sebeplere, iş yapabilecek tesir, kuvvet vermiştir. Bu kuvvetlere, tabiat kuvvetleri, fizik, kimya ve biyoloji kanunları diyoruz. Bir iş yapmamız, bir şeyi elde etmemiz için, bu işin sebeplerine yapışmamız lazımdır. Mesela buğday hasıl olması için, tarlayı sürmek, ekmek, ekini biçmek lazımdır. İnsanların bütün hareketleri, işleri, Allahü Teâlâ'nın bu âdeti içinde meydana gelmektedir. Allahü Teâlâ sevdiği insanlara iyilik, ikram olmak için ve azılı düşmanlarını aldatmak için bunlara, âdetini bozarak sebepsiz şeyler yaratıyor. *Çeşitli, lezzetli yemeklerle ve tatlı, soğuk şerbetlerle bedenlerinizi rahat ve hoş tutunuz. *Temiz ve yeni elbise giyiniz. Gittiğiniz yerlerde, ahlakınızla, sözlerinizle, İslam’ın vakarını, kıymetini gösterdiğiniz gibi, giyiminizle de saygı ve ilgi toplayınız. *Son zamanlarda, tekkeler cahillerin eline düştü. Dinden, imandan haberi olmayanlara şeyh denildi. Din düşmanları da, bu şeyhlerin sözlerini, oyunlarını ele alarak dine hurafeler karışmıştır, dedi. Halbuki bozuk tarikatçıların sözlerini, işlerini din sanmak, bunları tasavvuf büyükleri ile karıştırmak, çok yanlıştır. Dini bilmemek, anlamamaktır. Dinde söz sahibi olmak için, Ehl-i sünnet âlimlerini tanımak, o büyüklerin kitaplarını okuyup, iyi anlayabilmek ve bildiğini yapmak lazımdır. Böyle bir âlim bulunmazsa, din düşmanları, meydanı boş bulup, din adamı şekline girer. Vaazları ile, kitapları ile, gençlerin imanını çalarak millet ve memleketi felakete götürürler. *İslam dini, Allahü Teâlâ'nın, Cebrail ismindeki melek vasıtası ile, sevgili Peygamberi Muhammed aleyhisselama gönderdiği, insanların, dünyada ve ahirette rahat ve mesut olmalarını sağlayan, usul ve kaidelerdir. Bütün üstünlükler, faydalı şeyler, İslamiyet’in içindedir. Eski dinlerin görünür görünmez bütün iyiliklerini, İslamiyet, kendinde toplamıştır. Bütün saadetler, muvaffakiyetler ondadır. Yanılmayan, şaşırmayan, akılların kabul edeceği esaslardan ve ahlaktan ibarettir. Yaradılışında kusursuz olanlar onu reddetmez ve nefret etmez, İslamiyet’in içinde hiçbir zarar yoktur. İslamiyet’in dışında hiçbir menfaat yoktur ve olamaz. *Müslümanların öğrenmesi lazım olan bilgilere Ulum-i İslamiyye (Müslümanlık Bilgileri) denir. İslam dininin emrettiği bu bilgileri Resulullah aleyhisselam ikiye ayırmıştır. Biri, "ulum-i nakliyye", yani din bilgileri; diğeri "ulum-i akliyye" yani fen bilgileridir, buyurmuştur. Din bilgileri, dünyada ve ahirette, huzuru, saadeti kazandıran bilgilerdir. *:Bunlar da ikiye ayrılır: "Ulum-i aliyye" yani yüksek din bilgileri ve "ulum-i ibtidaiyye" yani alet ilimleri. İslam ilimlerinin ikinci kısmı olan akıl bilgilerinin yani tecrübi ilimlerin iyi öğrenilmesi, ince ve derin din bilgilerinin kolay ve açık anlaşılmasına yardım eder. Riyazi fizik öğrenmek, din bilgilerini kuvvetlendirir. Astronomi, aritmetik ve geometri, dine yardımcı bilgilerdir. Tecrübi fizikteki (tecrübe ve isbat edilenlere esasen uymayan) birkaç yanlış teori ve hipotezden başka hepsi dine uymakta, imanı kuvvetlendirmektedir. İlahi fizik (metafizik) bilgilerinden, çürük, bozuk olanları dine uymaz. Bu ilimler öğrenilince, din bilgilerinin akli ilimlere uyan ve akli bilgilerle çözülmeyen yerleri ve sebepleri meydana çıkar ve akla uygun sanılmayan, aklın erişemediği meselelerin inkâr edilemeyeceği anlaşılır. *İnsanı kaplayan sıkıntıların birinci sebebi, Hakk'a karşı şirk ve müşrikliktir. İlim ve fen ilerlediği halde, insanlığın ufuklarını sarmış olan fesat karanlığı hep şirkin, imansızlığın, vahdetsizliğin ve sevişmezliğin neticesidir. Beşeriyet ne kadar uğraşırsa uğraşsın, sevip sevilmedikçe, ıstırap ve felaketten kurtulamaz. Hakk'ı tanımadıkça, Hakk'ı sevmedikçe, Hak teâlâyı hakim bilip, Ona kulluk etmedikçe, insanlar, birbiri ile sevişemez. Hak'dan ve Hak yolundan başka her ne düşünülse, hepsi ayrılık ve perişanlık yoludur. *Evliyanın sözünde rabbani tesir vardır. *Büyüklerin sözü, sözlerin büyüğüdür. *Her peygamber, kendi zamanında, kendi mekanında, kendi kavminin hepsinden, her bakımdan üstündür. Muhammed aleyhisselam ise her zamanda her memlekette, yani dünya yaratıldığı günden kıyamet kopuncaya kadar, gelmiş ve gelecek, bütün varlıkların, her bakımdan en üstünüdür. Hiç kimse, hiçbir bakımdan Onun üstünde değildir. Bu olamayacak bir şey değildir. Dilediğini yapan, her istediğini yaratan, Onu böyle yaratmıştır. Hiçbir insanın Onu methedecek gücü yoktur. Hiçbir insanın Onu tenkit edecek iktidarı yoktur. *Hak Teâlâ'nın hakimliğini tanıdığınız, emaneti ve emniyeti bozmayarak çalıştığınız zaman, birbirinizi ne kadar sevecek, birbirinize ne kadar bağlı kardeşler olacaksınız. Sizin o kardeşliğinizden Allah’ın merhameti neler yaratacaktır. Kavuştuğunuz her nimet, hep Hakk'a imanın hasıl ettiği kardeşliğin neticesi ve Allahü Teâlâ'nın merhamet ve ihsanıdır. Gördüğünüz her musibet ve felaket de; hep kızgınlığın, nefretin ve düşmanlığın neticesidir. Bunlar ise hakkı tanımamanın, zulüm ve haksızlık etmenin cezasıdır. *Bahçıvan, bir gül için bin dikene su verir. == Kaynakça == ''Silsile-i Aliyye’nin Son Altun Halkası Seyyid Abdülhakîm-i Arvâsî Kuddise Sirruh Hazretleri'', Şaban Er-Fuâd Âsım Arvâs, Fusus Kitabevi, Tekirdağ, 2024. ''Arvâsî Seyyidleri Hânedânı Ve Hazret-i Şeyh Allâme Seyyid Fehîm-i Arvâsî Kuddise Sirruh'', Şaban Er-Fuâd Âsım Arvâs, Kutup Yıldızı Yayınları, İstanbul, 2023. Süleyman Kuku-Son Halkalar ve Seyyid Abdülhakîm Arvâsî’nin Külliyatı-1.Cilt [[Kategori:1943 yılında ölenler]] [[Kategori:Kişiler-A]] [[Kategori:Evliyalar]] [[Kategori:Türk mutasavvıflar]] [[Kategori:1860 doğumlular]] 5115pdevk2saogmvbdobbpy44vsvtqn 240650 240649 2026-10-17T07:59:20Z Esvc.emre 20239 240650 wikitext text/x-wiki {{Kaynaksız}} {{Biyografi |kişi_adı=Abdülhakîm Arvâsî Üçışık |resim_adı= |resim_başlığı= |doğum_tarihi=1860 |doğum_yeri=Başkale, Van, Osmanlı İmparatorluğu |ölüm_tarihi=27 Kasım 1943 |ölüm_yeri=Ankara, Türkiye }} '''Abdülhakîm Arvâsî Üçışık''' (1860, Başkale, Van - 1943, Ankara), Türk İslam âlimidir. ==Sözleri== *Cemiyetteki ruh hastalıklarının sebebi, iman eksikliğidir. *Riya olmasın diye cemaatten kaçanlar ayrı bir riya içindedirler. *Haramlardan korkan zahiddir. Şüpheliden korkan ise velidir. *Tek vakit namazımı kaçırmaktansa, bin kere ölmeyi tercih ederim. *Namaz, aman namaz, nerede ve ne şart altında olursa olsun mutlaka namaz kılın. *En büyük edep, ilahi hududu muhafazadır, gözetmektir. *Allahü Teâlâ bir kuluna iman vermişse ona daha ne vermemiştir. İman vermemişse ona daha ne vermiştir! *Bizim meclisimizde bulunanlar, sükut içinde otursalar ve sükuttan başka bir şey görmeseler bile, din bahsinde âlim geçinenlerin hatalarını keşfederler, bir bir çıkarırlar. *Kur'an-ı Kerim şifadır. Fakat şifa, suyun geldiği boruya tâbidir. Pis borudan şifa gelmez. *Gerçek keramet, kerametin gizlenmesidir. Bunun dışında görünenler, velinin irade ve ihtiyarı ile değildir. İlahi hikmet öyle gerektiriyor demektir. *Allahü Teâlâ sırrını eminine verir. Bilen söylemez, söyleyen bilmez. *Ahmaklık, hatada ısrar etmektir. *Kur'an-ı Kerim'den ve Resul aleyhisselamın hadis-i şeriflerinden sonra en kıymetli kitap, İmam-ı Rabbani hazretlerinin Mektubat kitabıdır. Hanefi mezhebinde en mükemmel ve en kıymetli fıkıh kitabı, İbni Abidin'in Dürrül-Muhtar haşiyesidir. Şafii’de Tuhfet-ül-Muhtac kitabıdır. *Din bilgileri, dünyada ve ahirette, huzuru, saadeti kazandıran bilgilerdir. *Allahü Teâlâ dilediğini yapar. İster sebepli ister sebepsiz, dilediği gibi azap veya lütfeder. Güzel ve doğru Onun dilediğidir. *Allahü Teâlâ bize rahmetiyle muamele etsin. Adaletiyle muamele ederse yanarız. *İlim cehli izale eder, yok eder, ahmaklığı değil. *Allahü Teâlâ, her şeyi bir sebep altında yaratmaktadır. Bu sebeplere, iş yapabilecek tesir, kuvvet vermiştir. Bu kuvvetlere, tabiat kuvvetleri, fizik, kimya ve biyoloji kanunları diyoruz. Bir iş yapmamız, bir şeyi elde etmemiz için, bu işin sebeplerine yapışmamız lazımdır. Mesela buğday hasıl olması için, tarlayı sürmek, ekmek, ekini biçmek lazımdır. İnsanların bütün hareketleri, işleri, Allahü Teâlâ'nın bu âdeti içinde meydana gelmektedir. Allahü Teâlâ sevdiği insanlara iyilik, ikram olmak için ve azılı düşmanlarını aldatmak için bunlara, âdetini bozarak sebepsiz şeyler yaratıyor. *Çeşitli, lezzetli yemeklerle ve tatlı, soğuk şerbetlerle bedenlerinizi rahat ve hoş tutunuz. *Temiz ve yeni elbise giyiniz. Gittiğiniz yerlerde, ahlakınızla, sözlerinizle, İslam’ın vakarını, kıymetini gösterdiğiniz gibi, giyiminizle de saygı ve ilgi toplayınız. *Son zamanlarda, tekkeler cahillerin eline düştü. Dinden, imandan haberi olmayanlara şeyh denildi. Din düşmanları da, bu şeyhlerin sözlerini, oyunlarını ele alarak dine hurafeler karışmıştır, dedi. Halbuki bozuk tarikatçıların sözlerini, işlerini din sanmak, bunları tasavvuf büyükleri ile karıştırmak, çok yanlıştır. Dini bilmemek, anlamamaktır. Dinde söz sahibi olmak için, Ehl-i sünnet âlimlerini tanımak, o büyüklerin kitaplarını okuyup, iyi anlayabilmek ve bildiğini yapmak lazımdır. Böyle bir âlim bulunmazsa, din düşmanları, meydanı boş bulup, din adamı şekline girer. Vaazları ile, kitapları ile, gençlerin imanını çalarak millet ve memleketi felakete götürürler. *İslam dini, Allahü Teâlâ'nın, Cebrail ismindeki melek vasıtası ile, sevgili Peygamberi Muhammed aleyhisselama gönderdiği, insanların, dünyada ve ahirette rahat ve mesut olmalarını sağlayan, usul ve kaidelerdir. Bütün üstünlükler, faydalı şeyler, İslamiyet’in içindedir. Eski dinlerin görünür görünmez bütün iyiliklerini, İslamiyet, kendinde toplamıştır. Bütün saadetler, muvaffakiyetler ondadır. Yanılmayan, şaşırmayan, akılların kabul edeceği esaslardan ve ahlaktan ibarettir. Yaradılışında kusursuz olanlar onu reddetmez ve nefret etmez, İslamiyet’in içinde hiçbir zarar yoktur. İslamiyet’in dışında hiçbir menfaat yoktur ve olamaz. *Müslümanların öğrenmesi lazım olan bilgilere Ulum-i İslamiyye (Müslümanlık Bilgileri) denir. İslam dininin emrettiği bu bilgileri Resulullah aleyhisselam ikiye ayırmıştır. Biri, "ulum-i nakliyye", yani din bilgileri; diğeri "ulum-i akliyye" yani fen bilgileridir, buyurmuştur. Din bilgileri, dünyada ve ahirette, huzuru, saadeti kazandıran bilgilerdir. *:Bunlar da ikiye ayrılır: "Ulum-i aliyye" yani yüksek din bilgileri ve "ulum-i ibtidaiyye" yani alet ilimleri. İslam ilimlerinin ikinci kısmı olan akıl bilgilerinin yani tecrübi ilimlerin iyi öğrenilmesi, ince ve derin din bilgilerinin kolay ve açık anlaşılmasına yardım eder. Riyazi fizik öğrenmek, din bilgilerini kuvvetlendirir. Astronomi, aritmetik ve geometri, dine yardımcı bilgilerdir. Tecrübi fizikteki (tecrübe ve isbat edilenlere esasen uymayan) birkaç yanlış teori ve hipotezden başka hepsi dine uymakta, imanı kuvvetlendirmektedir. İlahi fizik (metafizik) bilgilerinden, çürük, bozuk olanları dine uymaz. Bu ilimler öğrenilince, din bilgilerinin akli ilimlere uyan ve akli bilgilerle çözülmeyen yerleri ve sebepleri meydana çıkar ve akla uygun sanılmayan, aklın erişemediği meselelerin inkâr edilemeyeceği anlaşılır. *İnsanı kaplayan sıkıntıların birinci sebebi, Hakk'a karşı şirk ve müşrikliktir. İlim ve fen ilerlediği halde, insanlığın ufuklarını sarmış olan fesat karanlığı hep şirkin, imansızlığın, vahdetsizliğin ve sevişmezliğin neticesidir. Beşeriyet ne kadar uğraşırsa uğraşsın, sevip sevilmedikçe, ıstırap ve felaketten kurtulamaz. Hakk'ı tanımadıkça, Hakk'ı sevmedikçe, Hak teâlâyı hakim bilip, Ona kulluk etmedikçe, insanlar, birbiri ile sevişemez. Hak'dan ve Hak yolundan başka her ne düşünülse, hepsi ayrılık ve perişanlık yoludur. *Evliyanın sözünde rabbani tesir vardır. *Büyüklerin sözü, sözlerin büyüğüdür. *Her peygamber, kendi zamanında, kendi mekanında, kendi kavminin hepsinden, her bakımdan üstündür. Muhammed aleyhisselam ise her zamanda her memlekette, yani dünya yaratıldığı günden kıyamet kopuncaya kadar, gelmiş ve gelecek, bütün varlıkların, her bakımdan en üstünüdür. Hiç kimse, hiçbir bakımdan Onun üstünde değildir. Bu olamayacak bir şey değildir. Dilediğini yapan, her istediğini yaratan, Onu böyle yaratmıştır. Hiçbir insanın Onu methedecek gücü yoktur. Hiçbir insanın Onu tenkit edecek iktidarı yoktur. *Hak Teâlâ'nın hakimliğini tanıdığınız, emaneti ve emniyeti bozmayarak çalıştığınız zaman, birbirinizi ne kadar sevecek, birbirinize ne kadar bağlı kardeşler olacaksınız. Sizin o kardeşliğinizden Allah’ın merhameti neler yaratacaktır. Kavuştuğunuz her nimet, hep Hakk'a imanın hasıl ettiği kardeşliğin neticesi ve Allahü Teâlâ'nın merhamet ve ihsanıdır. Gördüğünüz her musibet ve felaket de; hep kızgınlığın, nefretin ve düşmanlığın neticesidir. Bunlar ise hakkı tanımamanın, zulüm ve haksızlık etmenin cezasıdır. *Bahçıvan, bir gül için bin dikene su verir. Kurbân kesmek için borç almak câ’iz değildir, ahmaklıktır. Kurbân, Şâfiʻîler’e göre istihsânî emrdir; sünnetdir. Hanefî’de, vâcibdir. Kurbân ne kadar yüksek fiyâtla alınırsa, bereketi de o kadar fazla olur. Cenâb-i Hakk, kendi yolunda sarf olunanlara yine verir. *Ehl-i Beyt-i Nebevî, Beytü’l-Mâl’deki ganîmetlerden beşte bir hisse aldıklarından, bunlara zekât verilmedi. Fakat Ehl-i Beyt, hissesini almadıkları vakt, Ehl-i Beyt’e zekât verilmesi câ’iz olur diye fetvâ verdiler. Öşr kaldırılmakla, öşr sâkıt olmaz, düşmez. Herkesin yine öşrünü vermesi lâzımdır. Öşrü verilmemiş zirâʻat mahsûlleri, harâmdır. Zekât verilmeyen paranın kırkta biri muʻayyen olmadığından, hepsi harâmdır. *Namâzın içindeki sünnetlerden her biri, geceyi ihyâ etmekten yaʻnî sabâha kadar ibâdet etmekten dahâ fazîletlidir. Zîrâ, namâzdaki sünnetleri yerine getirmekte, Peygamber Aleyhissalâtü Vesselâm’a tâbiʻ olmak, uymak fazîleti vardır. Bir Âyet-i Kerîme’de {Ey Habîbim! Onlara de ki: “Eğer Allâhü Te‘âlâ’yı seviyorsanız, hemen bana ittibâʻ ediniz, tâbiʻ olunuz!”} buyurulmaktadır. Bu Âyet-i Kerîme, Peygamber Aleyhissalâtü Vesselâm’a ittibâʻ etmek emrine riʻâyetin şerefini bildirmektedir. Namâzın içindeki sünnetler ve gâlibâ namâzın müstehabları da farzlara münkalib olurlar. Bu, çaya konan şekerin ve sâ’irenin çaya münkalib olması, çay hâlini alması, çaya dönüşmesi gibidir. *Bir kızın bir erkeğe bir vâsıta ile veyâ vâsıtasız olarak nikâh talebi câ’izdir ve hoşdur. *İslâmiyyet, dînin rüknlerini Ehl-i Sünnet’e muvâfık hâsıl etmek ve hulûs yaʻnî ihlâs hâsıl olmaktır. *Nefsin tasfiyesi kâfirlerde, râhiblerde, hakîmlerde olur. Kalbin tasfiyesi, mutlakâ îmânla alâkalıdır. Kalbin tasfiyesi, sâlih ameller olmadan olmaz. Sâlih ameller yapılmadan kalbin selâmet bulacağını söyleyen, mülhiddir. Nefsin tasfiyesinde sâlih amellerin lüzûmu yoktur. *Harâm yiyenin duʻâsı kabûl edilmez. Mü’mine en evvel lâzım olan, halâl yemesidir. Miʻdeye halâl girerse, vücûdun cevârihine sâlih amel yapmak kuvveti verir. Miʻdesine harâm giren kimse, ne kadar uğraşırsa uğraşsın, sâlih amel yapamaz. *Zaferin sadakası, intikâm almamaktır. *Âlimlerin ve sâlihlerin eli öpülür. Ramezân-i Şerîf orucunu tutmayanların, açıkta oruç yiyenlerin, zekât verilmesine mâniʻ olanların, zekât vermeyenlerin, namâz kılmayanların eli öpülmez. Öpülecek el kalmadı. Eli öpülecek kimseler, toprak altındadır. *İslâmiyyet, ferdlerde kaldı! Ammâ, hangi ferdlerde?! Pek nâdir, pek gizli ferdlerde!.. *Allâhü Te‘âlâ imhâl eder yaʻnî mühlet verir fakat ihmâl etmez. *Yetmiş iki bid‘at fırkasının muktedâları ya‘nî başları dîn âlimi idi fakat kendi akıllarını, dînlerine tercîh ettiler. *Mâlı hem harâmdan ve hem halâlden karışık olanın yemeğinden yemek, mekrûhdur. Zâlim sultânın mâlı, böyledir. *Kabir su’âli, hem rûhadır ve hem cesededir. “Yalnız rûhadır.” diyen veyâ “Yalnız cesededir.” diyen, kâfir olur. *Kalblerin meyli, zafer sebebidir. *Her zamân îmân lâzım olduğu gibi, her zamân tevbe de lâzımdır. *Dîn İlmleri, anlamak için değildir; inanmak içindir. *Herkes, îmânı nisbetinde Kur’ân’dan bir şey anlar. *Ölü bir kalbin ihyâsı, yüz senelik ölüyü ihyâ etmekten dahâ müşkildir. *Amellerin en fazîletlisi, iki müslimânın arasını bulmaktır. Bilhâssa dargın karı-kocanın. Hasta olan mü’mini ziyâret etmek, hastalıktan iyileşince tebrîk etmek, vefât edince cenâzesine gitmek, büyükleri ta‘zîm ve iclâl etmek, birbirini îkâz ve irşâd etmek, herkese karşı güzel ahlâklı olmak müslimânların birbirleri üzerindeki hakklarındandır. *Namâz nerede varsa, orada îmân vardır. Namâz nerede yoksa, orada îmân yâ vardır veyâ yoktur. Zîrâ, namâz kılmayan, tamâmen gâfildir. *Asıl kerâmet, istikâmetdir. Kim ki Şerîʻat Câddesi’nden ayrılmadı; o, kerâmetdir. == Kaynakça == ''Silsile-i Aliyye’nin Son Altun Halkası Seyyid Abdülhakîm-i Arvâsî Kuddise Sirruh Hazretleri'', Şaban Er-Fuâd Âsım Arvâs, Fusus Kitabevi, Tekirdağ, 2024. ''Arvâsî Seyyidleri Hânedânı Ve Hazret-i Şeyh Allâme Seyyid Fehîm-i Arvâsî Kuddise Sirruh'', Şaban Er-Fuâd Âsım Arvâs, Kutup Yıldızı Yayınları, İstanbul, 2023. Süleyman Kuku-Son Halkalar ve Seyyid Abdülhakîm Arvâsî’nin Külliyatı-1.Cilt [[Kategori:1943 yılında ölenler]] [[Kategori:Kişiler-A]] [[Kategori:Evliyalar]] [[Kategori:Türk mutasavvıflar]] [[Kategori:1860 doğumlular]] mak1j6nu654126nqhnao566pk4is4ko 240651 240650 2026-10-17T08:00:30Z Esvc.emre 20239 240651 wikitext text/x-wiki {{Kaynaksız}} {{Biyografi |kişi_adı=Abdülhakîm Arvâsî Üçışık |resim_adı= |resim_başlığı= |doğum_tarihi=1860 |doğum_yeri=Başkale, Van, Osmanlı İmparatorluğu |ölüm_tarihi=27 Kasım 1943 |ölüm_yeri=Ankara, Türkiye }} '''Abdülhakîm Arvâsî Üçışık''' (1860, Başkale, Van - 1943, Ankara), Türk İslam âlimidir. ==Sözleri== *Cemiyetteki ruh hastalıklarının sebebi, iman eksikliğidir. *Riya olmasın diye cemaatten kaçanlar ayrı bir riya içindedirler. *Haramlardan korkan zahiddir. Şüpheliden korkan ise velidir. *Tek vakit namazımı kaçırmaktansa, bin kere ölmeyi tercih ederim. *Namaz, aman namaz, nerede ve ne şart altında olursa olsun mutlaka namaz kılın. *En büyük edep, ilahi hududu muhafazadır, gözetmektir. *Allahü Teâlâ bir kuluna iman vermişse ona daha ne vermemiştir. İman vermemişse ona daha ne vermiştir! *Bizim meclisimizde bulunanlar, sükut içinde otursalar ve sükuttan başka bir şey görmeseler bile, din bahsinde âlim geçinenlerin hatalarını keşfederler, bir bir çıkarırlar. *Kur'an-ı Kerim şifadır. Fakat şifa, suyun geldiği boruya tâbidir. Pis borudan şifa gelmez. *Gerçek keramet, kerametin gizlenmesidir. Bunun dışında görünenler, velinin irade ve ihtiyarı ile değildir. İlahi hikmet öyle gerektiriyor demektir. *Allahü Teâlâ sırrını eminine verir. Bilen söylemez, söyleyen bilmez. *Ahmaklık, hatada ısrar etmektir. *Kur'an-ı Kerim'den ve Resul aleyhisselamın hadis-i şeriflerinden sonra en kıymetli kitap, İmam-ı Rabbani hazretlerinin Mektubat kitabıdır. Hanefi mezhebinde en mükemmel ve en kıymetli fıkıh kitabı, İbni Abidin'in Dürrül-Muhtar haşiyesidir. Şafii’de Tuhfet-ül-Muhtac kitabıdır. *Din bilgileri, dünyada ve ahirette, huzuru, saadeti kazandıran bilgilerdir. *Allahü Teâlâ dilediğini yapar. İster sebepli ister sebepsiz, dilediği gibi azap veya lütfeder. Güzel ve doğru Onun dilediğidir. *Allahü Teâlâ bize rahmetiyle muamele etsin. Adaletiyle muamele ederse yanarız. *İlim cehli izale eder, yok eder, ahmaklığı değil. *Allahü Teâlâ, her şeyi bir sebep altında yaratmaktadır. Bu sebeplere, iş yapabilecek tesir, kuvvet vermiştir. Bu kuvvetlere, tabiat kuvvetleri, fizik, kimya ve biyoloji kanunları diyoruz. Bir iş yapmamız, bir şeyi elde etmemiz için, bu işin sebeplerine yapışmamız lazımdır. Mesela buğday hasıl olması için, tarlayı sürmek, ekmek, ekini biçmek lazımdır. İnsanların bütün hareketleri, işleri, Allahü Teâlâ'nın bu âdeti içinde meydana gelmektedir. Allahü Teâlâ sevdiği insanlara iyilik, ikram olmak için ve azılı düşmanlarını aldatmak için bunlara, âdetini bozarak sebepsiz şeyler yaratıyor. *Çeşitli, lezzetli yemeklerle ve tatlı, soğuk şerbetlerle bedenlerinizi rahat ve hoş tutunuz. *Temiz ve yeni elbise giyiniz. Gittiğiniz yerlerde, ahlakınızla, sözlerinizle, İslam’ın vakarını, kıymetini gösterdiğiniz gibi, giyiminizle de saygı ve ilgi toplayınız. *Son zamanlarda, tekkeler cahillerin eline düştü. Dinden, imandan haberi olmayanlara şeyh denildi. Din düşmanları da, bu şeyhlerin sözlerini, oyunlarını ele alarak dine hurafeler karışmıştır, dedi. Halbuki bozuk tarikatçıların sözlerini, işlerini din sanmak, bunları tasavvuf büyükleri ile karıştırmak, çok yanlıştır. Dini bilmemek, anlamamaktır. Dinde söz sahibi olmak için, Ehl-i sünnet âlimlerini tanımak, o büyüklerin kitaplarını okuyup, iyi anlayabilmek ve bildiğini yapmak lazımdır. Böyle bir âlim bulunmazsa, din düşmanları, meydanı boş bulup, din adamı şekline girer. Vaazları ile, kitapları ile, gençlerin imanını çalarak millet ve memleketi felakete götürürler. *İslam dini, Allahü Teâlâ'nın, Cebrail ismindeki melek vasıtası ile, sevgili Peygamberi Muhammed aleyhisselama gönderdiği, insanların, dünyada ve ahirette rahat ve mesut olmalarını sağlayan, usul ve kaidelerdir. Bütün üstünlükler, faydalı şeyler, İslamiyet’in içindedir. Eski dinlerin görünür görünmez bütün iyiliklerini, İslamiyet, kendinde toplamıştır. Bütün saadetler, muvaffakiyetler ondadır. Yanılmayan, şaşırmayan, akılların kabul edeceği esaslardan ve ahlaktan ibarettir. Yaradılışında kusursuz olanlar onu reddetmez ve nefret etmez, İslamiyet’in içinde hiçbir zarar yoktur. İslamiyet’in dışında hiçbir menfaat yoktur ve olamaz. *Müslümanların öğrenmesi lazım olan bilgilere Ulum-i İslamiyye (Müslümanlık Bilgileri) denir. İslam dininin emrettiği bu bilgileri Resulullah aleyhisselam ikiye ayırmıştır. Biri, "ulum-i nakliyye", yani din bilgileri; diğeri "ulum-i akliyye" yani fen bilgileridir, buyurmuştur. Din bilgileri, dünyada ve ahirette, huzuru, saadeti kazandıran bilgilerdir. *:Bunlar da ikiye ayrılır: "Ulum-i aliyye" yani yüksek din bilgileri ve "ulum-i ibtidaiyye" yani alet ilimleri. İslam ilimlerinin ikinci kısmı olan akıl bilgilerinin yani tecrübi ilimlerin iyi öğrenilmesi, ince ve derin din bilgilerinin kolay ve açık anlaşılmasına yardım eder. Riyazi fizik öğrenmek, din bilgilerini kuvvetlendirir. Astronomi, aritmetik ve geometri, dine yardımcı bilgilerdir. Tecrübi fizikteki (tecrübe ve isbat edilenlere esasen uymayan) birkaç yanlış teori ve hipotezden başka hepsi dine uymakta, imanı kuvvetlendirmektedir. İlahi fizik (metafizik) bilgilerinden, çürük, bozuk olanları dine uymaz. Bu ilimler öğrenilince, din bilgilerinin akli ilimlere uyan ve akli bilgilerle çözülmeyen yerleri ve sebepleri meydana çıkar ve akla uygun sanılmayan, aklın erişemediği meselelerin inkâr edilemeyeceği anlaşılır. *İnsanı kaplayan sıkıntıların birinci sebebi, Hakk'a karşı şirk ve müşrikliktir. İlim ve fen ilerlediği halde, insanlığın ufuklarını sarmış olan fesat karanlığı hep şirkin, imansızlığın, vahdetsizliğin ve sevişmezliğin neticesidir. Beşeriyet ne kadar uğraşırsa uğraşsın, sevip sevilmedikçe, ıstırap ve felaketten kurtulamaz. Hakk'ı tanımadıkça, Hakk'ı sevmedikçe, Hak teâlâyı hakim bilip, Ona kulluk etmedikçe, insanlar, birbiri ile sevişemez. Hak'dan ve Hak yolundan başka her ne düşünülse, hepsi ayrılık ve perişanlık yoludur. *Evliyanın sözünde rabbani tesir vardır. *Büyüklerin sözü, sözlerin büyüğüdür. *Her peygamber, kendi zamanında, kendi mekanında, kendi kavminin hepsinden, her bakımdan üstündür. Muhammed aleyhisselam ise her zamanda her memlekette, yani dünya yaratıldığı günden kıyamet kopuncaya kadar, gelmiş ve gelecek, bütün varlıkların, her bakımdan en üstünüdür. Hiç kimse, hiçbir bakımdan Onun üstünde değildir. Bu olamayacak bir şey değildir. Dilediğini yapan, her istediğini yaratan, Onu böyle yaratmıştır. Hiçbir insanın Onu methedecek gücü yoktur. Hiçbir insanın Onu tenkit edecek iktidarı yoktur. *Hak Teâlâ'nın hakimliğini tanıdığınız, emaneti ve emniyeti bozmayarak çalıştığınız zaman, birbirinizi ne kadar sevecek, birbirinize ne kadar bağlı kardeşler olacaksınız. Sizin o kardeşliğinizden Allah’ın merhameti neler yaratacaktır. Kavuştuğunuz her nimet, hep Hakk'a imanın hasıl ettiği kardeşliğin neticesi ve Allahü Teâlâ'nın merhamet ve ihsanıdır. Gördüğünüz her musibet ve felaket de; hep kızgınlığın, nefretin ve düşmanlığın neticesidir. Bunlar ise hakkı tanımamanın, zulüm ve haksızlık etmenin cezasıdır. *Bahçıvan, bir gül için bin dikene su verir. *Kurbân kesmek için borç almak câ’iz değildir, ahmaklıktır. Kurbân, Şâfiʻîler’e göre istihsânî emrdir; sünnetdir. Hanefî’de, vâcibdir. Kurbân ne kadar yüksek fiyâtla alınırsa, bereketi de o kadar fazla olur. Cenâb-i Hakk, kendi yolunda sarf olunanlara yine verir. *Ehl-i Beyt-i Nebevî, Beytü’l-Mâl’deki ganîmetlerden beşte bir hisse aldıklarından, bunlara zekât verilmedi. Fakat Ehl-i Beyt, hissesini almadıkları vakt, Ehl-i Beyt’e zekât verilmesi câ’iz olur diye fetvâ verdiler. Öşr kaldırılmakla, öşr sâkıt olmaz, düşmez. Herkesin yine öşrünü vermesi lâzımdır. Öşrü verilmemiş zirâʻat mahsûlleri, harâmdır. Zekât verilmeyen paranın kırkta biri muʻayyen olmadığından, hepsi harâmdır. *Namâzın içindeki sünnetlerden her biri, geceyi ihyâ etmekten yaʻnî sabâha kadar ibâdet etmekten dahâ fazîletlidir. Zîrâ, namâzdaki sünnetleri yerine getirmekte, Peygamber Aleyhissalâtü Vesselâm’a tâbiʻ olmak, uymak fazîleti vardır. Bir Âyet-i Kerîme’de {Ey Habîbim! Onlara de ki: “Eğer Allâhü Te‘âlâ’yı seviyorsanız, hemen bana ittibâʻ ediniz, tâbiʻ olunuz!”} buyurulmaktadır. Bu Âyet-i Kerîme, Peygamber Aleyhissalâtü Vesselâm’a ittibâʻ etmek emrine riʻâyetin şerefini bildirmektedir. Namâzın içindeki sünnetler ve gâlibâ namâzın müstehabları da farzlara münkalib olurlar. Bu, çaya konan şekerin ve sâ’irenin çaya münkalib olması, çay hâlini alması, çaya dönüşmesi gibidir. *Bir kızın bir erkeğe bir vâsıta ile veyâ vâsıtasız olarak nikâh talebi câ’izdir ve hoşdur. *İslâmiyyet, dînin rüknlerini Ehl-i Sünnet’e muvâfık hâsıl etmek ve hulûs yaʻnî ihlâs hâsıl olmaktır. *Nefsin tasfiyesi kâfirlerde, râhiblerde, hakîmlerde olur. Kalbin tasfiyesi, mutlakâ îmânla alâkalıdır. Kalbin tasfiyesi, sâlih ameller olmadan olmaz. Sâlih ameller yapılmadan kalbin selâmet bulacağını söyleyen, mülhiddir. Nefsin tasfiyesinde sâlih amellerin lüzûmu yoktur. *Harâm yiyenin duʻâsı kabûl edilmez. Mü’mine en evvel lâzım olan, halâl yemesidir. Miʻdeye halâl girerse, vücûdun cevârihine sâlih amel yapmak kuvveti verir. Miʻdesine harâm giren kimse, ne kadar uğraşırsa uğraşsın, sâlih amel yapamaz. *Zaferin sadakası, intikâm almamaktır. *Âlimlerin ve sâlihlerin eli öpülür. Ramezân-i Şerîf orucunu tutmayanların, açıkta oruç yiyenlerin, zekât verilmesine mâniʻ olanların, zekât vermeyenlerin, namâz kılmayanların eli öpülmez. Öpülecek el kalmadı. Eli öpülecek kimseler, toprak altındadır. *İslâmiyyet, ferdlerde kaldı! Ammâ, hangi ferdlerde?! Pek nâdir, pek gizli ferdlerde!.. *Allâhü Te‘âlâ imhâl eder yaʻnî mühlet verir fakat ihmâl etmez. *Yetmiş iki bid‘at fırkasının muktedâları ya‘nî başları dîn âlimi idi fakat kendi akıllarını, dînlerine tercîh ettiler. *Mâlı hem harâmdan ve hem halâlden karışık olanın yemeğinden yemek, mekrûhdur. Zâlim sultânın mâlı, böyledir. *Kabir su’âli, hem rûhadır ve hem cesededir. “Yalnız rûhadır.” diyen veyâ “Yalnız cesededir.” diyen, kâfir olur. *Kalblerin meyli, zafer sebebidir. *Her zamân îmân lâzım olduğu gibi, her zamân tevbe de lâzımdır. *Dîn İlmleri, anlamak için değildir; inanmak içindir. *Herkes, îmânı nisbetinde Kur’ân’dan bir şey anlar. *Ölü bir kalbin ihyâsı, yüz senelik ölüyü ihyâ etmekten dahâ müşkildir. *Amellerin en fazîletlisi, iki müslimânın arasını bulmaktır. Bilhâssa dargın karı-kocanın. Hasta olan mü’mini ziyâret etmek, hastalıktan iyileşince tebrîk etmek, vefât edince cenâzesine gitmek, büyükleri ta‘zîm ve iclâl etmek, birbirini îkâz ve irşâd etmek, herkese karşı güzel ahlâklı olmak müslimânların birbirleri üzerindeki hakklarındandır. *Namâz nerede varsa, orada îmân vardır. Namâz nerede yoksa, orada îmân yâ vardır veyâ yoktur. Zîrâ, namâz kılmayan, tamâmen gâfildir. *Asıl kerâmet, istikâmetdir. Kim ki Şerîʻat Câddesi’nden ayrılmadı; o, kerâmetdir. == Kaynakça == ''Silsile-i Aliyye’nin Son Altun Halkası Seyyid Abdülhakîm-i Arvâsî Kuddise Sirruh Hazretleri'', Şaban Er-Fuâd Âsım Arvâs, Fusus Kitabevi, Tekirdağ, 2024. ''Arvâsî Seyyidleri Hânedânı Ve Hazret-i Şeyh Allâme Seyyid Fehîm-i Arvâsî Kuddise Sirruh'', Şaban Er-Fuâd Âsım Arvâs, Kutup Yıldızı Yayınları, İstanbul, 2023. Süleyman Kuku-Son Halkalar ve Seyyid Abdülhakîm Arvâsî’nin Külliyatı-1.Cilt [[Kategori:1943 yılında ölenler]] [[Kategori:Kişiler-A]] [[Kategori:Evliyalar]] [[Kategori:Türk mutasavvıflar]] [[Kategori:1860 doğumlular]] ivpc01th8i78jjtyr528t20947vxrxq Peter Dinklage 0 21983 240645 239107 2026-10-16T19:02:24Z Brightt11 34669 kategori ekleme (via JWB) 240645 wikitext text/x-wiki {{Biyografi}} '''[[w:Peter Dinklage|Peter Hayden Dinklage]]''' (d. 11 Haziran 1969) Amerikalı oyuncu ve film yapımcısı == Sözleri == *Bütün hayvanları seviyorum. Bir kediye, köpeğe, tavuğa ya da bir ineğe zarar veremem. Ve başka birisinden onlara benim adıma zarar vermesini isteyemem. Bu yüzden veganım. ** “[https://www.youtube.com/watch?v=6RlQwEgjCxE 'Game of Thrones' Star Peter Dinklage on Why He's Vegetarian],” ad for [[w:People for the Ethical Treatment of Animals|PETA]] (26 Ağustos 2011). [[Kategori:Kişiler-P]] [[Kategori:Amerikalı oyuncular]] [[Kategori:Amerikalı veganlar]] [[Kategori:1969 doğumlular]] [[Kategori:Yaşayan insanlar]] 4zvtelsvni3v392286d284eck3s61em Vikisöz:Değişiklik sayılarına göre kullanıcılar listesi 4 24934 240647 240619 2026-10-16T21:30:25Z YBot 18235 Güncelleme 240647 wikitext text/x-wiki {{/begin}} <center> {| class="wikitable" ! # ! Kullanıcı ! Değişiklik sayısı ! Kullanıcı grupları |- | 1 | [[Kullanıcı:Victor Trevor|Victor Trevor]] | align="center" | 19.119 | editör |- | 2 | [[Kullanıcı:Vitruvian|Vitruvian]] | align="center" | 13.188 | editör |- | 3 | [[Kullanıcı:Felecita|Felecita]] | align="center" | 8.758 | hizmetli |- | 4 | [[Kullanıcı:Nosferatü|Nosferatü]] | align="center" | 8.679 | editör |- | 5 | [[Kullanıcı:ToprakM|ToprakM]] | align="center" | 7.128 | editör, arayüz yöneticisi |- | 6 | [[Kullanıcı:Brightt11|Brightt11]] | align="center" | 5.342 | editör |- | 7 | [[Kullanıcı:Tarih|Tarih]] | align="center" | 4.802 | editör |- | 8 | [[Kullanıcı:Nanahuatl|Nanahuatl]] | align="center" | 4.453 | editör |- | 9 | [[Kullanıcı:Ölümsüz Sözler|Ölümsüz Sözler]] | align="center" | 4.372 | |- | 10 | [[Kullanıcı:Turgut46|Turgut46]] | align="center" | 4.212 | editör |- | 11 | [[Kullanıcı:Babatolian|Babatolian]] | align="center" | 3.527 | editör |- | 12 | [[Kullanıcı:Feyyaztiftik|Feyyaztiftik]] | align="center" | 3.254 | editör |- | 13 | [[Kullanıcı:Fuzûlî|Fuzûlî]] | align="center" | 2.588 | |- | 14 | [[Kullanıcı:Modern primat|Modern primat]] | align="center" | 2.139 | beyaz liste |- | 15 | [[Kullanıcı:Mavrikant|Mavrikant]] | align="center" | 2.078 | editör |- | 16 | [[Kullanıcı:Viki|Viki]] | align="center" | 1.972 | |- | 17 | [[Kullanıcı:Berrram|Berrram]] | align="center" | 1.959 | editör |- | 18 | [[Kullanıcı:New user message|New user message]] | align="center" | 1.854 | |- | 19 | [[Kullanıcı:Evrifaessa|Evrifaessa]] | align="center" | 1.784 | editör |- | 20 | [[Kullanıcı:HakanIST|HakanIST]] | align="center" | 1.762 | editör |- | 21 | [[Kullanıcı:Kibele|Kibele]] | align="center" | 1.611 | editör |- | 22 | [[Kullanıcı:Yusuf kayadüğün|Yusuf kayadüğün]] | align="center" | 1.549 | |- | 23 | [[Kullanıcı:Dabeon|Dabeon]] | align="center" | 1.446 | editör |- | 24 | [[Kullanıcı:Science|Science]] | align="center" | 1.397 | editör |- | 25 | [[Kullanıcı:Cekli829|Cekli829]] | align="center" | 1.385 | editör |- | 26 | [[Kullanıcı:Vito Genovese|Vito Genovese]] | align="center" | 1.346 | editör |- | 27 | [[Kullanıcı:CommonsDelinker|CommonsDelinker]] | align="center" | 1.166 | editör |- | 28 | [[Kullanıcı:Yomralı|Yomralı]] | align="center" | 1.166 | |- | 29 | [[Kullanıcı:Mustafa MVC|Mustafa MVC]] | align="center" | 1.107 | editör |- | 30 | [[Kullanıcı:II. Niveles|II. Niveles]] | align="center" | 1.042 | |- | 31 | [[Kullanıcı:Aguzer|Aguzer]] | align="center" | 986 | |- | 32 | [[Kullanıcı:Diyapazon|Diyapazon]] | align="center" | 960 | editör |- | 33 | [[Kullanıcı:Sabri76|Sabri76]] | align="center" | 916 | editör |- | 34 | [[Kullanıcı:Kadı|Kadı]] | align="center" | 860 | hizmetli |- | 35 | [[Kullanıcı:Ayshe17|Ayshe17]] | align="center" | 761 | |- | 36 | [[Kullanıcı:Uncitoyen|Uncitoyen]] | align="center" | 758 | editör |- | 37 | [[Kullanıcı:1980OmerYilmaz|1980OmerYilmaz]] | align="center" | 677 | beyaz liste |- | 38 | [[Kullanıcı:Reality006|Reality006]] | align="center" | 669 | |- | 39 | [[Kullanıcı:3210|3210]] | align="center" | 589 | |- | 40 | [[Kullanıcı:By erdo can|By erdo can]] | align="center" | 523 | editör |- | 41 | [[Kullanıcı:Pivox|Pivox]] | align="center" | 522 | editör |- | 42 | [[Kullanıcı:~2026-16868-14|~2026-16868-14]] | align="center" | 518 | |- | 43 | [[Kullanıcı:Elvorix|Elvorix]] | align="center" | 504 | editör |- | 44 | [[Kullanıcı:Pinar|Pinar]] | align="center" | 446 | editör |- | 45 | [[Kullanıcı:Amfetamin|Amfetamin]] | align="center" | 439 | |- | 46 | [[Kullanıcı:Henrymorgan92|Henrymorgan92]] | align="center" | 420 | editör |- | 47 | [[Kullanıcı:Renamed user 41d4a6caf1d82f0a356d4fa13ee53984|Renamed user 41d4a6caf1d82f0a356d4fa13ee53984]] | align="center" | 418 | |- | 48 | [[Kullanıcı:Pathoschild|Pathoschild]] | align="center" | 401 | |- | 49 | [[Kullanıcı:Kendim~trwikiquote|Kendim~trwikiquote]] | align="center" | 390 | |- | 50 | [[Kullanıcı:DrArdeN|DrArdeN]] | align="center" | 390 | editör |- | 51 | [[Kullanıcı:Tragic Kingdom|Tragic Kingdom]] | align="center" | 389 | editör |- | 52 | [[Kullanıcı:Tehonk|Tehonk]] | align="center" | 386 | editör |- | 53 | [[Kullanıcı:Dbl2010|Dbl2010]] | align="center" | 385 | |- | 54 | [[Kullanıcı:Placeboizm|Placeboizm]] | align="center" | 374 | editör |- | 55 | [[Kullanıcı:Zaitsév|Zaitsév]] | align="center" | 352 | editör |- | 56 | [[Kullanıcı:LM.CR|LM.CR]] | align="center" | 332 | editör |- | 57 | [[Kullanıcı:Fzelen06|Fzelen06]] | align="center" | 331 | |- | 58 | [[Kullanıcı:Kutsalyolcusu|Kutsalyolcusu]] | align="center" | 330 | editör |- | 59 | [[Kullanıcı:Slayerized|Slayerized]] | align="center" | 325 | |- | 60 | [[Kullanıcı:~2026-33042-03|~2026-33042-03]] | align="center" | 314 | |- | 61 | [[Kullanıcı:Therou|Therou]] | align="center" | 311 | editör |- | 62 | [[Kullanıcı:Melinoë|Melinoë]] | align="center" | 303 | editör |- | 63 | [[Kullanıcı:Suelnur|Suelnur]] | align="center" | 295 | |- | 64 | [[Kullanıcı:Koc61|Koc61]] | align="center" | 262 | |- | 65 | [[Kullanıcı:Merube 89|Merube 89]] | align="center" | 244 | |- | 66 | [[Kullanıcı:Egemensen~trwikiquote|Egemensen~trwikiquote]] | align="center" | 238 | |- | 67 | [[Kullanıcı:Refrenantem|Refrenantem]] | align="center" | 237 | |- | 68 | [[Kullanıcı:Tegel|Tegel]] | align="center" | 234 | |- | 69 | [[Kullanıcı:Gnosis58|Gnosis58]] | align="center" | 230 | |- | 70 | [[Kullanıcı:Ralph102|Ralph102]] | align="center" | 222 | beyaz liste |- | 71 | [[Kullanıcı:Gökhan|Gökhan]] | align="center" | 221 | |- | 72 | [[Kullanıcı:阿尔达|阿尔达]] | align="center" | 218 | |- | 73 | [[Kullanıcı:Sinestik|Sinestik]] | align="center" | 214 | editör |- | 74 | [[Kullanıcı:Kayra|Kayra]] | align="center" | 213 | editör |- | 75 | [[Kullanıcı:Sae1962|Sae1962]] | align="center" | 212 | editör |- | 76 | [[Kullanıcı:Mutlutopuz|Mutlutopuz]] | align="center" | 210 | editör |- | 77 | [[Kullanıcı:Ersene|Ersene]] | align="center" | 210 | beyaz liste |- | 78 | [[Kullanıcı:Duvardakiyazi|Duvardakiyazi]] | align="center" | 198 | |- | 79 | [[Kullanıcı:Hsngllc|Hsngllc]] | align="center" | 193 | |- | 80 | [[Kullanıcı:07|07]] | align="center" | 186 | editör |- | 81 | [[Kullanıcı:Mereyü|Mereyü]] | align="center" | 181 | editör |- | 82 | [[Kullanıcı:Mors et Vita|Mors et Vita]] | align="center" | 178 | beyaz liste |- | 83 | [[Kullanıcı:Dbilgener|Dbilgener]] | align="center" | 177 | |- | 84 | [[Kullanıcı:Stultiwikia|Stultiwikia]] | align="center" | 176 | editör |- | 85 | [[Kullanıcı:Normike|Normike]] | align="center" | 166 | |- | 86 | [[Kullanıcı:Dakmor Tojira|Dakmor Tojira]] | align="center" | 164 | editör |- | 87 | [[Kullanıcı:Thomas|Thomas]] | align="center" | 163 | |- | 88 | [[Kullanıcı:Ata Barış|Ata Barış]] | align="center" | 155 | editör |- | 89 | [[Kullanıcı:Fatih.cyd|Fatih.cyd]] | align="center" | 151 | |- | 90 | [[Kullanıcı:Hazan|Hazan]] | align="center" | 149 | editör |- | 91 | [[Kullanıcı:Türkolog1984|Türkolog1984]] | align="center" | 146 | |- | 92 | [[Kullanıcı:Yahya1967|Yahya1967]] | align="center" | 141 | |- | 93 | [[Kullanıcı:Habil Özdemir|Habil Özdemir]] | align="center" | 137 | |- | 94 | [[Kullanıcı:SHIFT64|SHIFT64]] | align="center" | 136 | beyaz liste |- | 95 | [[Kullanıcı:ArthurBot|ArthurBot]] | align="center" | 132 | |- | 96 | [[Kullanıcı:Pusula Ölümsüz Sözler|Pusula Ölümsüz Sözler]] | align="center" | 131 | |- | 97 | [[Kullanıcı:Urungu97|Urungu97]] | align="center" | 129 | editör |- | 98 | [[Kullanıcı:Perfims|Perfims]] | align="center" | 127 | |- | 99 | [[Kullanıcı:Alaattin savas|Alaattin savas]] | align="center" | 120 | |- | 100 | [[Kullanıcı:Amia222|Amia222]] | align="center" | 119 | |} </center> kkgzo27svoty4ibci6ofdm7fqi38ap4 Vikisöz:AutoWikiBrowser 4 26358 240634 237381 2026-10-16T16:18:17Z Brightt11 34669 240634 wikitext text/x-wiki {{AWB uyarı}} {{AWB uyarı 2}} {{Kısayol2|VS:AWB}} [[Dosya:Awbscreenshot.PNG|küçükresim|300pik|AutoWikiBrowser arayüzü]] '''AutoWikiBrowser''' (genellikle kısaltılmış olarak '''AWB'''), tekrarlayan görevleri daha hızlı ve kolay hale getirmek için tasarlanmış olan bir yarı-otomatik MediaWiki düzenleme yazılımıdır. Windows XP ve üzeri işletim sistemlerinde çalışmaktadır. AWB, [[Wikipedia:tr:Linux|Linux]] ve [[Wikipedia:tr:OS X|Mac]] üzerinde de oldukça iyi çalışmaktadır ama resmî olarak desteklenmez. Yazılım, [[Wikipedia:tr:C Sharp|C#]] programlama dili kullanılarak [[Wikipedia:tr:Microsoft Visual Studio|Microsoft Visual Studio]] ile yazılmıştır ve kaynak kodları [[Wikipedia:tr:GNU Genel Kamu Lisansı|GPLv2]] lisansı altındadır. == Yazılımı kullanmak == === (1) Başvur === Yazılımı kullanmak isterseniz, '''<mark>[[Vikisöz:AutoWikiBrowser/Başvuru|bu]]</mark>''' sayfaya uygun bir gerekçeyle başvuru yapmanız gerekmektedir. === (2) İndir === Son sürümünü '''<mark>[https://sourceforge.net/projects/autowikibrowser/ buradan]</mark>''' indirin. Birden fazla olabildiğinden, Sourceforge sayfasındaki doğru indirme düğmesine tıkladığınızdan emin olun. Doğru düğme yeşil ve açıklamayı içeren kutunun içinde, ekran görüntülerinin hemen üstünde. En yeni SVN sürümünü çalıştırmak isterseniz [[w:Wikipedia:AutoWikiBrowser/Sources|kaynaklar]] sayfasına bakın. ==== Windows üzerinde çalıştırmak ==== AWB bir [[zip]] dosyası ile gelir ve örneğin masaüstünden doğrudan çalıştırmak yerine yeni bir klasöre çıkartılması önerilir. AWB bilgisayara yüklenmemiştir ve yalnızca bir dosya olarak çalıştırılır bu dosya: AutoWikiBrowser.exe (ayrıca WikiFunctions.dll dosyası da gereklidir) dosyasıdır. AWB herhangi bir dizine çıkartılabilir; ancak, bazı makinelerde kullanılan dizin bir ağ sürücüsündeyse AWB'nin doğru çalışmasını durduran izin sorunları olabilir. Emin değilseniz, AWB'yi makinenin C:\ sürücüsünde, örneğin 'İndirilenler' bölümünde bir yere çıkarın. AutoWikiBrowser'ı çalıştırmak için [[:w:Windows XP]] veya üzeri gereklidir. Ayrıca [[:w:.NET Framework]] Sürüm 3.5 veya üzeri de gerekir. [https://support.microsoft.com/help/14223 Microsoft desteğini kestiğini bildirse de] [[:w:Windows 2000|2000]]/[[:w:Windows XP|XP]] üzerinde hâlâ çalışmaktadır, ama Windows 2000 ve Windows XP kullanıcıları mutlaka <span class="plainlinks">[https://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe .NET Framework 3.5 sürümünü indirip kurmalıdır]</span> ([[:w:Windows Vista|Windows Vista]]'ya dahili olarak gelir). ==== Linux/Mac üzerinde çalıştırmak ==== [[:W:Linux]]'ta AWB çoğunlukla .NET 3.5 yüklü olan [[w:Wine|Wine]] ile çalışır ve düzenli düzenleme için uygundur. AWB, bazı garip hatalar olsa da [[Mono (yazılım)|Mono]]'da başlatılabilir fakat web tarayıcı bileşeni henüz Mono'da çalışmaz. Mono'nun altındaki AWB, henüz düzenli düzenleme için uygun değildir. [[w:Mac|Mac]]'te AWB doğal olarak mevcut değildir, ancak bir seçenek [[:w:Parallels Desktop for Mac|Mac için Parallels Desktop]] ile [[:w:sanallaştırma|sanallaştırma]]yı ([[:w:Parallels Desktop for Mac#Supported operating systems|toplantıyı destekleyen işletim sistemi gereksinimlerine]] tabidir) kullanmak ve daha sonra yukarıdaki Windows talimatları uyarınca AWB ile [[:w:Microsoft Windows]]'u çalıştırmaktır. Hem Parallels Desktop for Mac hem de Microsoft Windows için bir lisans gerektiği için bu seçeneğin özgür olmadığına dikkat edin. Diğer bir alternatif ücretsiz [[:w:VirtualBox|Virtualbox]]'ı kullanmaktır. AWB, Mac'te Wine altında da kullanılabilir. WineHQ'nun MacOS X altındaki Wine başlıklı bir sayfası vardır. === (3) Başlarken === # "Make from Category" öğesini seçin, ardından bir kategori adı girin. # "Make list" öğesine tıklayın, listenin yüklenmesine izin verin. # Bul ve değiştir, özet düzenleme vb. gibi seçenekleri ayarlayın. # "Start!" öğesine tıklayın, sayfayı yükleyecek, değişiklikleri otomatik olarak yapacak ve sonra farklılıklar gösterilecektir. # Tarayıcıdaki normal web sitesi metin kutusuna değil, sağ alt taraftaki Düzenle kutusunda istediğiniz sayfadaki herhangi bir şeyi değiştirip, ardından "Save" veya "Skip / Ignore" seçeneğini tıkladığınızda, bir sonraki sayfa otomatik olarak yüklenecektir. Daha fazla sorunun cevabını [[w:Wikipedia talk:AutoWikiBrowser#Frequently asked questions|SSS]] sayfasında bulabilirsiniz. == AWB kullanıcıları == * [[Vikisöz:AutoWikiBrowser/CheckPage]] == Ayrıca bakınız == * [[Vikisöz:AutoWikiBrowser/Typos]] * [[:en:Wikiquote:AutoWikiBrowser|Wikiquote:AutoWikiBrowser]] {{en}} ==Dış bağlantılar== * [https://sourceforge.net/projects/autowikibrowser/ Sourceforge proje sayfası] [[Kategori:AutoWikiBrowser| ]] [[Kategori:Vikisöz araçları]] cyadlgyon818fnkw18l0aru9cyr3hzp Vikisöz:Günün sözü/2006/11/04 4 31807 240631 171072 2026-10-16T13:31:18Z Roxy5958 30884 imla 240631 wikitext text/x-wiki İnsanların canları sıkıldığında sizden gidiyorsa ona tüm kapıları kapatın. 3qdmo316rx2xrgz48zugfhr173lrth0 Peter Handke 0 35351 240646 225037 2026-10-16T19:03:17Z Brightt11 34669 kategori ekleme (via JWB) 240646 wikitext text/x-wiki {{Biyografi}} '''Peter Handke''' (d. 6 Aralık 1942, Griffen, Avusturya), Avusturyalı romancı ve oyun yazarı. * Yalnızlık en buz gibi, en iğrenç acıyı doğurur. Gerçeklikten kopmuşluğun acısı. İnsanın o zaman birilerine ihtiyacı olur, bize durumun henüz o kadar da kötü olmadığını gösterecek birilerine... [[Kategori:Kişiler-P]] [[Kategori:Avusturyalı yazarlar]] [[Kategori:Nobel Edebiyat Ödülü sahipleri]] grhkfem8grtghcn2ityp0q078vqqnyo Kullanıcı:Brightt11/common.js 2 45362 240632 240630 2026-10-16T16:15:39Z Brightt11 34669 forked from enwiki. -->> https://en.wikipedia.org/wiki/User:Joeytje50/JWB.js 240632 javascript text/javascript /* who is active başlangıcı */ $( function () { const filteredLinks = []; const localizedUserNamespace = mw.config.get( 'wgFormattedNamespaces' )[2]; $( '.mw-parser-output' ). find( 'a[title^="User:"], a[title^="' + localizedUserNamespace + ':"]' ). each( function() { const link = $( this ); const href = decodeURI( link.attr( 'href' ) ); const userRegex = new RegExp( '((User)|(' + localizedUserNamespace + ')):(.*?)(?=&|$)' ); const username = href.match(userRegex); const index = username[0].indexOf( '/' ); if ( username[0].indexOf( '/' ) === -1 ) { filteredLinks.push( { username: username[0], element: link } ); } } ); if ( !filteredLinks.length ) { return; } const RECENT = 'recent'; const THISYEAR = 'thisyear'; const OVERAYEAR = 'overayear'; const messages = { en: { recent: 'Edited recently', thisyear: 'Edited this year', overayear: 'Edited over a year ago' }, tr: { recent: 'Aktif', thisyear: 'Yarı aktif', overayear: 'Aktif değil' }, de: { recent: 'kürzlich bearbeitet', thisyear: 'in diesem Jahr bearbeitet', overayear: 'vor über einem Jahr bearbeitet' } }; const localizedMessages = function () { const lang = mw.config.get( 'wgUserLanguage' ); if ( lang in messages ) { return messages[lang]; } return messages.en; }(); const getLastActiveMarker = function ( timestamp ) { const date = Date.parse( timestamp ); const now = Date.now(); const diff = Math.floor( ( now - date ) / ( 1000 * 60 * 60 * 24 ) ); var timespan = RECENT; if ( diff > 365 ) { timespan = OVERAYEAR; } else if ( diff > 15 ) { timespan = THISYEAR; } const iconPath = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/resources/lib/ooui/themes/wikimediaui/images/icons/userContributions-ltr.svg'; const marker = "<span class='mw-whoisactivegadget-span mw-whoisactivegadget-" + timespan + "'>" + "<img src='" + iconPath + "' class='mw-whoisactivegadget-filter-" + timespan + "'/> " + localizedMessages[timespan] + "<span>"; return $( marker ); }; mw.loader.using( [ 'mediawiki.api' ], function () { filteredLinks.forEach( function( item ) { const username = item.username; const element = item.element; const api = new mw.Api(); api.get( { format: 'json', action: 'query', list: 'usercontribs', uclimit: '1', ucuser: username } ).then( function ( result ) { if ( result.query.usercontribs.length ) { const timestamp = result.query.usercontribs[0].timestamp; getLastActiveMarker( timestamp ).insertAfter( element ); } } ); } ); } ); } ); /*who is active sonu*/ /* twinkle başlangıcı /* /** * +-------------------------------------------------------------------------+ * | === WARNING: GLOBAL GADGET FILE === | * | Changes to this page affect many users. | * | Please discuss changes at [[WT:TW]] before editing. | * +-------------------------------------------------------------------------+ * * Imported from github [https://github.com/wikimedia-gadgets/twinkle]. * All changes should be made in the repository, otherwise they will be lost. * * ---------- * * This is AzaToth's Twinkle, the popular script sidekick for newbies, admins, and * every Wikipedian in between. Visit [[WP:TW]] for more information. */ // <nowiki> /* global Morebits */ (function() { // Check if account is experienced enough to use Twinkle if (!Morebits.userIsInGroup('autoconfirmed') && !Morebits.userIsInGroup('confirmed')) { return; } const Twinkle = {}; window.Twinkle = Twinkle; // allow global access Twinkle.initCallbacks = []; /** * Adds a callback to execute when Twinkle has loaded. * * @param {Function} func * @param {string} [name] - name of module used to check if is disabled. * If name is not given, module is loaded unconditionally. */ Twinkle.addInitCallback = function twinkleAddInitCallback(func, name) { Twinkle.initCallbacks.push({ func: func, name: name }); }; Twinkle.defaultConfig = {}; /** * This holds the default set of preferences used by Twinkle. * It is important that all new preferences added here, especially admin-only ones, are also added to * |Twinkle.config.sections| in twinkleconfig.js, so they are configurable via the Twinkle preferences panel. * For help on the actual preferences, see the comments in twinkleconfig.js. */ Twinkle.defaultConfig = { // General userTalkPageMode: 'tab', dialogLargeFont: false, disabledModules: [], disabledSysopModules: [], // ARV spiWatchReport: 'yes', // Block defaultToBlock64: false, defaultToPartialBlocks: false, blankTalkpageOnIndefBlock: false, // Rollback autoMenuAfterRollback: false, openTalkPage: [ 'agf', 'norm', 'vand' ], openTalkPageOnAutoRevert: false, rollbackInPlace: false, markRevertedPagesAsMinor: [ 'vand' ], watchRevertedPages: [ 'agf', 'norm', 'vand', 'torev' ], watchRevertedExpiry: '1 month', offerReasonOnNormalRevert: true, confirmOnRollback: false, confirmOnMobileRollback: true, showRollbackLinks: [ 'diff', 'others' ], // DI (twinkleimage) notifyUserOnDeli: true, deliWatchPage: '1 month', deliWatchUser: '1 month', // Protect watchRequestedPages: 'yes', watchPPTaggedPages: 'default', watchProtectedPages: 'default', // PROD watchProdPages: '1 month', markProdPagesAsPatrolled: false, prodReasonDefault: '', logProdPages: false, prodLogPageName: 'BS günlüğü', // CSD speedySelectionStyle: 'buttonClick', watchSpeedyPages: [ 'g3', 'g5', 'g10', 'g11', 'g12' ], watchSpeedyExpiry: '1 month', markSpeedyPagesAsPatrolled: false, watchSpeedyUser: '1 month', // these next two should probably be identical by default welcomeUserOnSpeedyDeletionNotification: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], notifyUserOnSpeedyDeletionNomination: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], warnUserOnSpeedyDelete: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], promptForSpeedyDeletionSummary: [], deleteTalkPageOnDelete: true, deleteRedirectsOnDelete: true, deleteSysopDefaultToDelete: false, speedyWindowHeight: 500, speedyWindowWidth: 800, logSpeedyNominations: false, speedyLogPageName: 'HS günlüğü', noLogOnSpeedyNomination: [ 'g6' ], //Buradaki u1 -> g6 ve yukarıdaki db -> sil güncellemelerinden başka değişiklik yapılmadı. // Unlink unlinkNamespaces: [ '0', '10', '100', '118' ], // Warn defaultWarningGroup: '10', combinedSingletMenus: false, showSharedIPNotice: true, watchWarnings: '1 month', oldSelect: false, customWarningList: [], // XfD logXfdNominations: false, xfdLogPageName: 'SAS günlüğü', noLogOnXfdNomination: [], xfdWatchDiscussion: 'default', xfdWatchList: 'no', xfdWatchPage: '1 month', xfdWatchUser: '1 month', xfdWatchRelated: '1 month', markXfdPagesAsPatrolled: true, // Hidden preferences autolevelStaleDays: 3, // Huggle is 3, CBNG is 2 revertMaxRevisions: 50, // intentionally limited batchMax: 5000, batchChunks: 50, // Deprecated options, as a fallback for add-on scripts/modules summaryAd: ' ([[VP:TW|TW]])', deletionSummaryAd: ' ([[VP:TW|TW]])', protectionSummaryAd: ' ([[VP:TW|TW]])', // Tag groupByDefault: true, watchTaggedVenues: ['articles', 'drafts', 'redirects', 'files'], watchTaggedPages: '1 month', watchMergeDiscussions: '1 month', markTaggedPagesAsMinor: false, markTaggedPagesAsPatrolled: false, tagArticleSortOrder: 'cat', customTagList: [], customFileTagList: [], customRedirectTagList: [], // Welcome topWelcomes: false, watchWelcomes: '3 months', insertUsername: true, quickWelcomeMode: 'norm', quickWelcomeTemplate: 'welcome', customWelcomeList: [], customWelcomeSignature: true, // Talkback markTalkbackAsMinor: false, insertTalkbackSignature: true, // always sign talkback templates talkbackHeading: mw.config.get('wgUserName') + ' adlı kullanıcıdan yeni bir mesaj', mailHeading: "E-postanız var!", // Shared markSharedIPAsMinor: true }; Twinkle.getPref = function twinkleGetPref(name) { if (typeof Twinkle.prefs === 'object' && Twinkle.prefs[name] !== undefined) { return Twinkle.prefs[name]; } // Old preferences format, used before twinkleoptions.js was a thing if (typeof window.TwinkleConfig === 'object' && window.TwinkleConfig[name] !== undefined) { return window.TwinkleConfig[name]; } if (typeof window.FriendlyConfig === 'object' && window.FriendlyConfig[name] !== undefined) { return window.FriendlyConfig[name]; } // Backwards compatibility code because we renamed confirmOnFluff to confirmOnRollback, and confirmOnMobileFluff to confirmOnMobileRollback if (name === 'confirmOnRollback' && typeof Twinkle.prefs === 'object' && Twinkle.prefs.confirmOnFluff !== undefined) { return Twinkle.prefs.confirmOnFluff; } else if (name === 'confirmOnMobileRollback' && typeof Twinkle.prefs === 'object' && Twinkle.prefs.confirmOnMobileFluff !== undefined) { return Twinkle.prefs.confirmOnMobileFluff; } return Twinkle.defaultConfig[name]; }; /** * Adds a portlet menu to one of the navigation areas on the page. * * @return {string} portletId */ Twinkle.addPortlet = function() { /** @type {string} id of the target navigation area (skin dependent, on vector either of "#left-navigation", "#right-navigation", or "#mw-panel") */ let navigation; /** @type {string} id of the portlet menu to create, preferably start with "p-". */ let id; /** @type {string} name of the portlet menu to create. Visibility depends on the class used. */ let text; /** @type {Node} the id of the node before which the new item should be added, should be another item in the same list, or undefined to place it at the end. */ let nextnodeid; switch (mw.config.get('skin')) { case 'vector': case 'vector-2022': navigation = '#right-navigation'; id = 'p-twinkle'; text = 'TW'; // In order to get mw.util.addPortlet to generate a dropdown menu in vector and vector-2022, the nextnodeid must be p-cactions. Any other nextnodeid will generate a non-dropdown portlet instead. nextnodeid = 'p-cactions'; break; case 'timeless': navigation = '#page-tools .sidebar-inner'; id = 'p-twinkle'; text = 'Twinkle'; nextnodeid = 'p-userpagetools'; break; default: navigation = null; id = 'p-cactions'; } if (navigation === null) { return id; } // make sure navigation is a valid CSS selector const root = document.querySelector(navigation); if (!root) { return id; } // if we already created the portlet, return early. we don't want to create it again. const item = document.getElementById(id); if (item) { return id; } mw.util.addPortlet(id, text, '#' + nextnodeid); // The Twinkle dropdown menu has been added to the left of p-cactions, since that is the only spot that will create a dropdown menu. But we want it on the right. Move it to the right. if (mw.config.get('skin') === 'vector') { $('#p-twinkle').insertAfter('#p-cactions'); } else if (mw.config.get('skin') === 'vector-2022') { const $landmark = $('#right-navigation > .vector-page-tools-landmark'); $('#p-twinkle-dropdown').insertAfter($landmark); // .vector-page-tools-landmark is unstable and could change. If so, log it to console, to hopefully get someone's attention. if (!$landmark) { mw.log.warn('Unexpected change in DOM'); } } return id; }; /** * Builds a portlet menu if it doesn't exist yet, and adds a portlet link. This function runs at the top of every Twinkle module, ensuring that the first module to be loaded adds the portlet, and that every module can add a link to itself to the portlet. * * @param task Either a URL for the portlet link or a function to execute. */ Twinkle.addPortletLink = function(task, text, id, tooltip) { // Create a portlet to hold all the portlet links (if not created already). And get the portletId. const portletId = Twinkle.addPortlet(); // Create a portlet link and add it to the portlet. const link = mw.util.addPortletLink(portletId, typeof task === 'string' ? task : '#', text, id, tooltip); // Related to the hidden peer gadget that prevents jumpiness when the page first loads $('.client-js .skin-vector #p-cactions').css('margin-right', 'initial'); // Add a click listener for the portlet link if (typeof task === 'function') { $(link).on('click', (ev) => { task(); ev.preventDefault(); }); } // $.collapsibleTabs is a feature of Vector 2010 if ($.collapsibleTabs) { // Manually trigger a recalculation of what tabs to put where. This is to account for the space that the TW menu we just added is taking up. $.collapsibleTabs.handleResize(); } return link; }; /** * **************** General initialization code **************** */ const scriptpathbefore = mw.util.wikiScript('index') + '?title=', scriptpathafter = '&action=raw&ctype=text/javascript&happy=yes'; // Retrieve the user's Twinkle preferences $.ajax({ url: scriptpathbefore + 'Kullanıcı:' + encodeURIComponent(mw.config.get('wgUserName')) + '/twinkleoptions.js' + scriptpathafter, dataType: 'text' }) .fail(() => { console.log('Twinkle tercihleriniz yüklenemedi, varsayılan tercihlere başvuruluyor'); // eslint-disable-line no-console }) .done((optionsText) => { // Quick pass if user has no options if (optionsText === '') { return; } // Twinkle options are basically a JSON object with some comments. Strip those: optionsText = optionsText.replace(/(?:^(?:\/\/[^\n]*\n)*\n*|(?:\/\/[^\n]*(?:\n|$))*$)/g, ''); // First version of options had some boilerplate code to make it eval-able -- strip that too. This part may become obsolete down the line. if (optionsText.lastIndexOf('window.Twinkle.prefs = ', 0) === 0) { optionsText = optionsText.replace(/(?:^window.Twinkle.prefs = |;\n*$)/g, ''); } try { const options = JSON.parse(optionsText); if (options) { if (options.twinkle || options.friendly) { // Old preferences format Twinkle.prefs = $.extend(options.twinkle, options.friendly); } else { Twinkle.prefs = options; } // v2 established after unification of Twinkle/Friendly objects Twinkle.prefs.optionsVersion = Twinkle.prefs.optionsVersion || 1; } } catch (e) { mw.notify('Twinkle tercihleriniz ayrıştırılamadı', {type: 'error'}); } }) .always(() => { $(Twinkle.load); }); // Developers: you can import custom Twinkle modules here // For example, mw.loader.load(scriptpathbefore + "User:UncleDouggie/morebits-test.js" + scriptpathafter); Twinkle.load = function () { // Don't activate on special pages other than those listed here, so // that others load faster, especially the watchlist. let activeSpecialPageList = [ 'Block', 'Contributions', 'Recentchanges', 'Recentchangeslinked' ]; // wgRelevantUserName defined for non-sysops on Special:Block if (Morebits.userIsSysop) { activeSpecialPageList = activeSpecialPageList.concat([ 'DeletedContributions', 'Prefixindex' ]); } if (mw.config.get('wgNamespaceNumber') === -1 && activeSpecialPageList.indexOf(mw.config.get('wgCanonicalSpecialPageName')) === -1) { return; } // Prevent clickjacking if (window.top !== window.self) { return; } // Set custom Api-User-Agent header, for server-side logging purposes Morebits.wiki.Api.setApiUserAgent('Twinkle (' + mw.config.get('wgWikiID') + ')'); Twinkle.disabledModules = Twinkle.getPref('disabledModules').concat(Twinkle.getPref('disabledSysopModules')); // Redefine addInitCallback so that any modules being loaded now on are directly // initialised rather than added to initCallbacks array Twinkle.addInitCallback = function(func, name) { if (!name || Twinkle.disabledModules.indexOf(name) === -1) { func(); } }; // Initialise modules that were saved in initCallbacks array Twinkle.initCallbacks.forEach((module) => { Twinkle.addInitCallback(module.func, module.name); }); // Increases text size in Twinkle dialogs, if so configured if (Twinkle.getPref('dialogLargeFont')) { mw.util.addCSS('.morebits-dialog-content, .morebits-dialog-footerlinks { font-size: 100% !important; } ' + '.morebits-dialog input, .morebits-dialog select, .morebits-dialog-content button { font-size: inherit !important; }'); } // Hide the lingering space if the TW menu is empty const isVector = mw.config.get('skin') === 'vector' || mw.config.get('skin') === 'vector-2022'; if (isVector && Twinkle.getPref('portletType') === 'menu' && $('#p-twinkle').length === 0) { $('#p-cactions').css('margin-right', 'initial'); } // If using a skin with space for lots of modules, display a link to Twinkle Preferences const usingSkinWithDropDownMenu = mw.config.get('skin') === 'vector' || mw.config.get('skin') === 'vector-2022' || mw.config.get('skin') === 'timeless'; if (usingSkinWithDropDownMenu) { Twinkle.addPortletLink(mw.util.getUrl('Vikipedi:Twinkle/Tercihler'), 'Tercihler', 'tw-config', 'Twinkle tercihler sayfasını aç'); } }; /** * Twinkle-specific data shared by multiple modules * Likely customized per installation */ // Custom change tag(s) to be applied to all Twinkle actions, create at Special:Tags Twinkle.changeTags = 'twinkle'; // Available for actions that don't (yet) support tags // currently: FlaggedRevs and PageTriage Twinkle.summaryAd = ' ([[VP:TW|TW]])'; // Various hatnote templates, used when tagging (csd/xfd/tag/prod/protect) to // ensure MOS:ORDER Twinkle.hatnoteRegex = 'short description|kısa açıklama|hatnote|[İi]lknot|main|ana|correct title|doğru madde adı|dablink|distinguish|karıştırma|for|[İi]çin|further|daha fazla|selfref|year dab|similar names|highway detail hatnote|broader|about(?:-distinguish| other people)?|hakkında||other\\s?(?:hurricane(?: use)?s|people|persons|places|ships|uses(?: of)?)|redirect(?:-(?:distinguish|synonym|multi))?||yönlendirme|see\\s?(?:wiktionary|also(?: if exists)?)'; /* Twinkle-specific utility functions shared by multiple modules */ /** * When performing rollbacks with [rollback] links, then visiting a user talk page, some data such as page name can be prefilled into Wel/AIV/Warn. Twinkle calls this a "prefill". This method gets a prefill, either from URL parameters (e.g. &vanarticle=Test) or from data previously stored using Twinkle.setPrefill() */ Twinkle.getPrefill = function (key) { Twinkle.prefill = Twinkle.prefill || {}; if (!Object.prototype.hasOwnProperty.call(Twinkle.prefill, key)) { Twinkle.prefill[key] = mw.util.getParamValue(key); } return Twinkle.prefill[key]; }; /** * When performing rollbacks with [rollback] links, then visiting a user talk page, some data such as page name can be prefilled into Wel/AIV/Warn. Twinkle calls this a "prefill". This method sets a prefill. This data will be lost if the page is refreshed, unless it is added to the URL as a parameter. */ Twinkle.setPrefill = function (key, value) { Twinkle.prefill = Twinkle.prefill || {}; Twinkle.prefill[key] = value; }; /* * Used in XFD and PROD */ Twinkle.makeFindSourcesDiv = function makeSourcesDiv(divID) { if (!$(divID).length) { return; } if (!Twinkle.findSources) { const parser = new Morebits.wiki.Preview($(divID)[0]); parser.beginRender('({{Kaynak ara|' + Morebits.pageNameNorm + '}})', 'VP:SAS').then(() => { // Save for second-time around Twinkle.findSources = parser.previewbox.innerHTML; $(divID).removeClass('morebits-previewbox'); }); } else { $(divID).html(Twinkle.findSources); } }; /** * Used in batch, unlink, and deprod to sort pages by namespace, as * json formatversion=2 sorts by pageid instead (#1251) */ Twinkle.sortByNamespace = function(first, second) { return first.ns - second.ns || (first.title > second.title ? 1 : -1); }; /** * Used in batch listings to link to the page in question with > */ Twinkle.generateArrowLinks = function (checkbox) { const link = Morebits.htmlNode('a', ' >'); link.setAttribute('class', 'tw-arrowpage-link'); link.setAttribute('href', mw.util.getUrl(checkbox.value)); link.setAttribute('target', '_blank'); checkbox.nextElementSibling.append(link); }; /** * Used in deprod and unlink listings to link the page title */ Twinkle.generateBatchPageLinks = function (checkbox) { const $checkbox = $(checkbox); const link = Morebits.htmlNode('a', $checkbox.val()); link.setAttribute('class', 'tw-batchpage-link'); link.setAttribute('href', mw.util.getUrl($checkbox.val())); link.setAttribute('target', '_blank'); $checkbox.next().prepend([link, ' ']); }; }()); // </nowiki> /* twinkle sonu */ /* JWB başlangıcı */ /** <nowiki> * Install this script by pasting the following in your personal JavaScript file: mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript'); * Or for users on en.wikipedia.org: {{subst:lusc|User:Joeytje50/JWB.js/load.js}} * Note that this script will only run on the 'Project:AutoWikiBrowser/Script' page. * This script is based on the downloadable AutoWikiBrowser. * * @licence * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html * @version 4.5.2 * @author Joeytje50 * </nowiki> */ window.JWBdeadman = false; // ADMINS: in case of fire, set this variable to true to disable this entire tool for all users //TODO: more advanced pagelist-generating options //TODO: generate page list based on images on a page //TODO: Add feature to perform general cleanup (<table> to {|, fullurl-links to wikilinks, removing underscores from wikilinks) //TODO: Add report button to AJAX error alert box //TODO: Re-add errored pages to the page list //TODO: Automatically generate full list of protection levels //TODO: Add 'Ignore quotes' alongside 'Ignore unparsed content'; for example: Ignore [] Unparsed content [] Quotes //TODO: Read Wikipedia:AutoWikiBrowser/Config for when not to apply typo fixes //TODO: RETF disable any \b and some other cases //TODO: Fix deletedrevs deprecated API //TODO: Handle response 429 (Too Many Requests) by rate-limiting Pre-parse mode //Cleanup / modernize: // .indexOf('') != -1 -> .includes() // mw for requests, instead of ajax // Optional?.chaining?.properties /***** Global object/variables *****/ window.JWB = {}; //The main global object for the script. (function() { // Easier way to change import location for local debugging etc. JWB.imports = { 'JWB.css': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.css&action=raw&ctype=text/css', 'i18n.js': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/i18n.js&action=raw&ctype=text/javascript', 'i18n': {}, 'RETF.js': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/RETF.js&action=raw&ctype=text/javascript', 'worker.js':'//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/worker.js&action=raw&ctype=text/javascript', }; JWB.allLoaded = false; let objs = ['page', 'api', 'worker', 'fn', 'pl', 'messages', 'setup', 'settings', 'ns']; for (let i=0;i<objs.length;i++) { JWB[objs[i]] = {}; } JWB.summarySuffix = ' (via JWB)'; if (document.location.hostname == 'en.wikipedia.org') JWB.summarySuffix = ' (via [[WP:JWB]])'; JWB.lang = mw.config.get('wgUserLanguage').replace('-', '_'); JWB.contentLang = mw.config.get('wgContentLanguage').replace('-', '_'); JWB.index_php = mw.config.get('wgScript'); JWB.isStopped = true; JWB.tooltip = window.tooltipAccessKeyPrefix || ''; let configext = 'js'; if (document.location.hostname.split('.').slice(-2).join('.') == 'wikia.com' || document.location.hostname.split('.').slice(-2).join('.') == 'fandom.com') { //LEGACY: fallback to settings on css for Wikia; uses JSON now. configext = 'css'; } JWB.settingspage = 'JWB-settings.'+configext; if (window.hasOwnProperty('JWBSETTINGS')) { JWB.settingspage = JWBSETTINGS+'-settings.'+configext; delete window.JWBSETTINGS; //clean up the global variable } JWB.hasJSON = false; // whether or not the wiki supports JSON userpages (mw 1.31+). JWB.hasSMW = false; // whether or not the wiki has SMW installed. })(); /***** User verification *****/ (function() { if (mw.config.get('wgCanonicalNamespace')+':'+mw.config.get('wgTitle') !== 'Project:AutoWikiBrowser/Script' || JWB.allowed === false || mw.config.get('wgUserName') === null) { JWB.allowed = false; return; } mw.loader.load(JWB.imports['JWB.css'], 'text/css'); mw.loader.load('mediawiki.diff.styles'); JWB.langs = []; $.getScript(JWB.imports['i18n.js'], function() { if (JWB.allowed === false) { JWB.checkInit(); // deny access without attempting to load other languages. return; } if (JWB.lang !== 'en' && JWB.imports.i18n.hasOwnProperty(JWB.lang)) { JWB.langs.push(JWB.imports.i18n[JWB.lang]); JWB.messages[JWB.lang] = JWB.messages[JWB.lang] || null; } else if (JWB.lang !== 'en' && JWB.lang !== 'qqx') { // this only happens if the language file does not exist. JWB.lang = 'en'; } if (JWB.contentLang !== 'en' && JWB.contentLang !== JWB.lang && JWB.imports.i18n.hasOwnProperty(JWB.contentLang)) { JWB.langs.push(JWB.imports.i18n[JWB.contentLang]); JWB.messages[JWB.contentLang] = JWB.messages[JWB.contentLang] || null; } if (JWB.langs.length) { $.when.apply($, JWB.langs.map(url => $.getScript(url))).done(function(r) { JWB.checkInit(); }); } else { // no more languages to load. console.log('no languages needed loading'); JWB.checkInit(); } }); //RegEx Typo Fixing $.getScript(JWB.imports['RETF.js'], function() { $('#refreshRETF').click(RETF.load); }); if (window.JWBdeadman === true) { window.JWB = false; // disable all access alert("This tool has been temporarily been disabled by Wikipedia admins due to issues it would otherwise cause. Please check back soon to see if it is working again."); return false; } else if (!window.Worker) { // https://caniuse.com/webworkers - this should not happen for any sensible human being. Either you're on IE<10, or you're just testing my patience. alert("Web Workers are not supported in this browser. Please use a more modern browser to use JWB. Most matching and replacing features are not supported in this browser."); } (new mw.Api()).get({ action: 'query', titles: 'Project:AutoWikiBrowser/CheckPageJSON|MediaWiki:Tag-JWB', prop: 'info|revisions', meta: 'userinfo|siteinfo', rvprop: 'content', uiprop: 'groups', siprop: 'namespaces|usergroups|extensions', indexpageids: true, format: 'json', }).done(function(response) { if (response.error) { alert('API error: ' + response.error.info); JWB = false; //preventing further access. No verification => no access. return; } JWB.ns = response.query.namespaces; //saving for later // This will execute before JWB.init() and therefore before JWB.setup.load() loading the user's settings. let wikigroups = response.query.usergroups; for (var u of wikigroups) { if (u.rights.indexOf('edituserjson') !== -1) { JWB.hasJSON = true; break; } } // Check if we've got SMW on this wiki let extensions = response.query.extensions; for (var e of extensions) { if (e.name == "SemanticMediaWiki") { JWB.hasSMW = true; break; } } JWB.username = response.query.userinfo.name; //preventing any "hacks" that change wgUserName or mw.config.wgUserName var groups = response.query.userinfo.groups; var page = Object.values(response.query.pages).find(page => page.title.includes("AutoWikiBrowser/CheckPageJSON")); var tagPage = Object.values(response.query.pages).find(page => page.title.includes("Tag-JWB")); JWB.hasTag = (tagPage.missing === undefined); var users = []; var bots = []; JWB.sysop = groups.indexOf('sysop') !== -1; if (response.query.pageids[0] !== '-1') { var checkPageData = JSON.parse(page.revisions[0]['*']); users = checkPageData.enabledusers; if ("enabledbots" in checkPageData) { bots = checkPageData.enabledbots; } } else { users = false; //fallback when page doesn't exist if (JWB.sysop) { // Check and inform admins if their checkpage is the unsupported format. (new mw.Api()).get({ action: 'query', titles: 'Project:AutoWikiBrowser/CheckPage', prop: 'info', indexpageids: true, }).done(function(oldpage){ var q = oldpage.query; if (q.pageids[0] != '-1' && !q.pages[q.pageids[0]].hasOwnProperty('redirect')) { // CheckPageJSON does not exist, and CheckPage does exist, and is not a redirect. // This indicates the checkpage needs to be ported to JSON. Notify admins. prompt('Warning: The AWB checkpage found at Project:AutoWikiBrowser/CheckPage is no longer supported.\n'+ 'Please convert this checkpage to a JSON checkpage. See the URL below for more information.\n'+ 'After creating the JSON checkpage, you can use "Special:ChangeContentModel" to change the content model to JSON.', 'https://en.wikipedia.org/wiki/Wikipedia:AutoWikiBrowser/CheckPage_format'); } }); } } JWB.bot = groups.indexOf('bot') !== -1 && (users === false || bots.includes(JWB.username)); // Temporary global debugging variables JWB.debug = [groups.indexOf('bot'), users === false, bots && bots.indexOf(JWB.username)]; if (JWB.username === "Joeytje50" && response.query.userinfo.id === 13299994) {//TEMP: Dev full access to entire interface. JWB.bot = true; users.push("Joeytje50"); } if (JWB.sysop || response.query.pageids[0] === '-1' || users === false || users.includes(JWB.username) || bots.includes(JWB.username)) { JWB.allowed = true; JWB.checkInit(); //init if everything necessary has been loaded } else { if (JWB.allLoaded) { //run this after messages have loaded, so the message that shows is in the user's language alert(JWB.msg('not-on-list')); } JWB = false; //prevent further access } }).fail(function(xhr, error) { alert(JWB.msg('verify-error') + '\n' + error); JWB = false; //preventing further access. No verification => no access. }); })(); /***** API functions *****/ //Main template for API calls JWB.api.call = function(data, callback, onerror) { data.format = 'json'; if (data.action !== 'query' && data.action !== 'compare' && data.action !== 'ask' && data.action !== 'parse' && data.action !== 'watch') { data.bot = true; // mark edits as bot if (JWB.hasTag) data.tags = 'JWB'; // tag with 'JWB' } $.ajax({ data: data, dataType: 'json', url: mw.config.get('wgScriptPath') + '/api.php', type: 'POST', success: function(response) { if (response.error) { if (onerror && onerror(response, 'API') === false) return; alert('API error: ' + response.error.info); JWB.stop(); } else { callback(response); } }, // onerror: if it exists and returns false, do not show error alert. Otherwise, do show alert. error: function(xhr, error) { if (onerror && onerror(error, 'AJAX') === false) return; alert('AJAX error: ' + error); JWB.stop(); } }); }; //Get page diff, and process it for more interactivity JWB.api.diff = function(callback) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('diff'); var editBoxInput = $('#editBoxArea').val(); var redirect = $('input.redirects:checked').val(); var data = { action: 'compare', indexpageids: true, fromtitle: JWB.page.name, //toslots: 'main', // TODO: Once this gets supported more widely, convert to the non-deprecated toslots system. //'totext-main': editBoxInput, totext: editBoxInput, topst: true, }; if (redirect=='follow') data.redirects = true; JWB.api.call(data, function(response) { var diff; diff = response.compare['*']; if (diff === '') { diff = '<h2>'+JWB.msg('no-changes-made')+'</h2>'; } else { diff = '<table class="diff">'+ '<colgroup>'+ '<col class="diff-marker">'+ '<col class="diff-content">'+ '<col class="diff-marker">'+ '<col class="diff-content">'+ '</colgroup>'+ '<tbody>'+diff+'</tbody></table>'; } $('#resultWindow').html(diff); $('.diff-lineno').each(function() { var lineNumMatch = $(this).html().match(/\d+/); if (lineNumMatch) { $(this).parent().attr('data-line',parseInt(lineNumMatch[0])-1).addClass('lineheader'); } }); $('table.diff tr').each(function() { //add data-line attribute to every line, relative to the previous one. Used for click event. if (!$(this).next().is('[data-line]') && !$(this).next().children('td.diff-deletedline + td.diff-empty').length) { $(this).next().attr('data-line',parseInt($(this).data('line'))+1); } else if ($(this).next().children('td.diff-deletedline + td.diff-empty').length) { $(this).next().attr('data-line',$(this).data('line')); //copy over current data-line for deleted lines to prevent them from messing up counting. } }); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } }, function(err, type) { if (type == 'API' && err.error.code == 'missingtitle') { // missingtitle is to be expected when editing a page that doesn't exist; just show a message and move on. $('#resultWindow').html('<span style="font-weight:bold;color:red;">'+JWB.msg('page-not-exists')+'</span>'); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } return false; // stop propagation of error; do not show alerts. } }); }; //Retrieve page contents/info, process them, and store information in JWB.page object. JWB.api.get = function(pagename) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.pageCount(); if (!JWB.list[0] || JWB.isStopped) { return JWB.stop(); } if (pagename === '#PRE-PARSE-STOP') { var curval = $('#articleList').val(); $('#articleList').val(curval.substr(curval.indexOf('\n') + 1)); $('#preparse').prop('checked', false); JWB.stop(); return; } let cgns = JWB.ns[14]['*']; let skipcg = $('#skipCategories').val(); // prepend Category: before all categories and turn CSV(,) into CSV(|). skipcg = skipcg.replace(new RegExp('(^|,|\\|)('+cgns+':)?', 'gi'), '|'+cgns+':').substr(1); var redirect = $('input.redirects:checked').val(); var data = { action: 'query', prop: 'info|revisions|categories', inprop: 'watched|protection', type: 'csrf|watch', titles: pagename, rvprop: 'content|timestamp|ids', rvlimit: '1', cllimit: 'max', clcategories: skipcg, indexpageids: true, meta: 'userinfo|tokens', uiprop: 'hasmsg' }; if (redirect=='follow'||redirect=='skip') data.redirects = true; if (JWB.sysop) { data.list = 'deletedrevs'; } JWB.status('load-page'); JWB.api.call(data, function(response) { if (response.query.userinfo.hasOwnProperty('messages')) { var view = mw.config.get('wgScriptPath') + '?title=Special:MyTalk'; var viewNew = view + '&diff=cur'; JWB.status( '<span style="color:red;font-weight:bold;">'+ JWB.msg('status-newmsg', '<a href="'+view+'" target="_blank">'+JWB.msg('status-talklink')+'</a>', '<a href="'+viewNew+'" target="_blank">'+JWB.msg('status-difflink')+'</a>')+ '</span>', true); alert(JWB.msg('new-message')); JWB.stop(); return; } JWB.page = response.query.pages[response.query.pageids[0]]; JWB.page.token = response.query.tokens.csrftoken; JWB.page.watchtoken = response.query.tokens.watchtoken; JWB.page.name = JWB.list[0].split('|')[0]; var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0; JWB.page.pagevar = JWB.list[0].substr(varOffset); JWB.page.content = JWB.page.revisions ? JWB.page.revisions[0]['*'] : ''; JWB.page.exists = !response.query.pages["-1"]; JWB.page.deletedrevs = response.query.deletedrevs; JWB.page.watched = JWB.page.hasOwnProperty('watched'); JWB.page.protections = JWB.page.restrictiontypes; if (response.query.redirects) { JWB.page.name = response.query.redirects[0].to; } JWB.page.path = mw.config.get('wgArticlePath').replace('$1', encodeURIComponent(JWB.page.name)); // check for skips that can be determined before replacing if (!JWB.fn.allowBots(JWB.page.content, JWB.username) || !JWB.fn.allowBots(JWB.page.content)) { // skip if {{bots}} template forbids editing on this page by user OR by JWB in general JWB.log('nobots', JWB.page.name); return JWB.next(); } else if (JWB.page.categories !== undefined || // skip because of a matching category as passed via clcategories. ($('#exists-no').prop('checked') && !JWB.page.exists) || ($('#exists-yes').prop('checked') && JWB.page.exists) || (redirect==='skip' && response.query.redirects) // variable redirect is defined outside this callback function. ) { // simple skip rules JWB.log('skip', JWB.page.name); return JWB.next(); } // Check skip contains rules. var containRegex = $('#containRegex').prop('checked'), containFlags = $('#containFlags').val(); var skipContains, skipNotContains; if (containRegex) { JWB.status('check-skips'); var skipping = false; // for tracking if match is found in synchronous calls. if ($('#skipContains').val().length) { JWB.worker.match(JWB.page.content, $('#skipContains').val(), containFlags, function(result, err) { console.log('Contains', result, err); if (result !== null && err === undefined) { JWB.log('skip', JWB.page.name); JWB.next(); // next() also cancels the skipNotContains. skipping = true; return; } // else continue with the queued worker job that checks skipNotContains }); } if (skipping) { console.log('skipped page before replaces'); return; } if ($('#skipNotContains').val().length) { JWB.worker.match(JWB.page.content, $('#skipNotContains').val(), containFlags, function(result, err) { console.log('Not contains', result, err); if (result === null && err === undefined) { JWB.log('skip', JWB.page.name); JWB.next(); // also cancels the replace skipping = true; return; } // else move on to replacing }); } if (skipping) { console.log('skipped page before replaces'); return; } } else { skipContains = $('#skipContains').val(); skipNotContains = $('#skipNotContains').val(); if ((skipContains && JWB.page.content.includes(skipContains)) || (skipNotContains && !JWB.page.content.includes(skipNotContains))) { console.log('skipped page before replaces'); return JWB.next(); } JWB.status('done', true); } JWB.replace(JWB.page.content, function(newContent) { if (JWB.isStopped === true) return; if ($('#skipNoChange').prop('checked') && JWB.page.content === newContent) { //skip if no changes are made JWB.log('skip', JWB.page.name); return JWB.next(); } else { JWB.editPage(newContent); } JWB.updateButtons(); }); }); }; //Some functions with self-explanatory names: JWB.api.submit = function(page) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('submit'); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; if ((typeof page === 'string' && page !== JWB.page.name) || $('#currentpage a').html().replace(/&amp;/g, '&') !== JWB.page.name) { console.log(page, JWB.page.name, $('#currentpage a').html()); JWB.stop(); alert(JWB.msg('autosave-error', JWB.msg('tab-log'))); $('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' ')); return; } var newval = $('#editBoxArea').val(); var diffsize = newval.length - JWB.page.content.length; if ($('#sizelimit').val() != 0 && Math.abs(diffsize) > parseInt($('#sizelimit').val())){ alert(JWB.msg('size-limit-exceeded', diffsize > 0 ? '+'+diffsize : diffsize)); JWB.status('done', true); return; } var data = { title: JWB.page.name, summary: summary, action: 'edit', basetimestamp: JWB.page.revisions ? JWB.page.revisions[0].timestamp : '', token: JWB.page.token, text: newval, watchlist: $('#watchPage').val() }; if ($('#minorEdit').prop('checked')) data.minor = true; JWB.api.call(data, function(response) { JWB.log('edit', response.edit.title, response.edit.newrevid); }, function(error, errtype) { var cont = false; if (errtype == 'API') { cont = confirm("API error: " + error.error.info + "\n" + JWB.msg('confirm-continue')); } else { cont = confirm("AJAX error: " + error + "\n" + JWB.msg('confirm-continue')); } if (!cont) { JWB.stop(); } return false; // do not fall back on default error handling }); // While the edit is submitting, continue to the next page to edit. JWB.status('done', true); JWB.next(); }; JWB.api.preview = function(callback) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('preview'); JWB.api.call({ title: JWB.page.name, action: 'parse', pst: true, text: $('#editBoxArea').val(), prop: 'text|categorieshtml|modules|jsconfigvars', useskin: mw.config.get('skin') }, function(response) { $('#resultWindow').html(response.parse.text['*']); $('#resultWindow div.previewnote').remove(); $('#resultWindow').append(response.parse.categorieshtml['*']); for (var entry of Object.entries(response.parse.jsconfigvars)) { mw.config.set(entry[0], entry[1]); } mw.loader.using(response.parse.modules.concat(response.parse.modulescripts, response.parse.modulestyles), function() { mw.hook('wikipage.content').fire($('#resultWindow .mw-parser-output')); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } }); }); }; JWB.api.move = function() { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('move'); var topage = $('#moveTo').val().replace(/\$x/gi, JWB.page.pagevar); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var data = { action: 'move', from: JWB.page.name, to: topage, token: JWB.page.token, reason: summary, ignorewarnings: 'yes' }; if ($('#moveTalk').prop('checked')) data.movetalk = true; if ($('#moveSubpage').prop('checked')) data.movesubpages = true; if ($('#suppressRedir').prop('checked')) data.noredirect = true; JWB.api.call(data, function(response) { JWB.log('move', response.move.from, response.move.to); JWB.status('done', true); if (!$('#moveTo').val().match(/\$x/i)) $('#moveTo').val('')[0].focus(); //clear entered move-to pagename if it's not based on the pagevar JWB.next(topage); }); }; JWB.api.del = function() { if (JWB.isStopped) return; // prevent new API calls when stopped var del_action = (!JWB.page.exists ? 'un' : '') + 'delete'; JWB.status(del_action); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var data = { action: del_action, title: JWB.page.name, token: JWB.page.token, reason: summary }; if ($('#deleteTalk').prop('checked')) data[del_action + 'talk'] = true; JWB.api.call(data, function(response) { JWB.log(del_action, (response['delete']||response.undelete).title); JWB.status('done', true); JWB.next(response.undelete && response.undelete.title); }); }; JWB.api.protect = function() { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('protect'); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var editprot = $('#editProt').val(); var moveprot = $('#moveProt').val() || editprot; var uploadprot = $('#uploadProt').val() || editprot; var protstring = 'edit='+editprot+'|move='+moveprot; if (!JWB.page.exists) protstring = 'create='+editprot; if (JWB.page.protections.includes('upload')) protstring += '|upload='+uploadprot; JWB.api.call({ action: 'protect', title: JWB.page.name, token: JWB.page.token, reason: summary, expiry: $('#protectExpiry').val()!==''?$('#protectExpiry').val():'infinite', protections: protstring, }, function(response) { var protactions = ''; var prots = response.protect.protections; for (var i=0;i<prots.length;i++) { if (typeof prots[i].edit == 'string') { protactions += ' edit: '+(prots[i].edit || 'all'); } else if (typeof prots[i].move == 'string') { protactions += ' move: '+(prots[i].move || 'all'); } else if (typeof prots[i].create == 'string') { protactions += ' create: '+(prots[i].create || 'all'); } else if (typeof prots[i].upload == 'string') { protactions += ' upload: '+(prots[i].upload || 'all'); } } protactions += ' expires: '+prots[0].expiry; JWB.log('protect', response.protect.title, protactions); JWB.status('done', false); JWB.next(response.protect.title); }); }; JWB.api.watch = function() { JWB.status('watch'); var data = { action: 'watch', title: JWB.page.name, token: JWB.page.watchtoken }; if (JWB.page.watched) data.unwatch = true; JWB.api.call(data, function(response) { JWB.status('<span style="color:green;">'+ JWB.msg('status-watch-'+(JWB.page.watched ? 'removed' : 'added'), "'"+JWB.page.name+"'")+ '</span>', true); JWB.page.watched = !JWB.page.watched; $('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) ); }); }; /***** Pagelist functions *****/ JWB.pl.iterations = 0; JWB.pl.done = true; JWB.pl.stop = function() { if (JWB.pl.done) { JWB.pl.iterations = 0; $('#pagelistPopup [disabled]:not(fieldset [disabled]), #pagelistPopup legend input, #pagelistPopup button').prop('disabled', false); $('#pagelistPopup legend input').trigger('change'); $('#pagelistPopup button img').remove(); } }; JWB.pl.getNSpaces = function() { var list = $('#pagelistPopup [name="namespace"]')[0]; return $('#pagelistPopup [name="namespace"]').val().join('|'); //.val() returns an array of selected options. }; JWB.pl.getList = function(abbrs, lists, data) { $('#pagelistPopup button, #pagelistPopup input, #pagelistPopup select, #pagelistPopup button').prop('disabled', true); JWB.pl.iterations++; if (data.ask !== undefined) { JWB.pl.SMW(data.ask); // execute SMW call in parallel JWB.pl.done = false; data.ask = undefined; } if (!abbrs.length) { JWB.pl.done = true; return; // don't execute the rest; only a SMW query was entered. } data.action = 'query'; var nspaces = JWB.pl.getNSpaces(); for (let i=0;i<abbrs.length;i++) { if (nspaces) data[abbrs[i]+'namespace'] = data[abbrs[i]+'namespace'] || nspaces; // if namespaces are already set, use that instead (for apnamespace) data[abbrs[i]+'limit'] = 'max'; } let linksList = lists.indexOf('links'); if (linksList !== -1) { data.prop = 'links'; lists.splice(linksList, 1); } data.list = lists.join('|'); console.log('generating:', data); JWB.api.call(data, function(response) { var maxiterate = 100; //allow up to 100 consecutive requests at a time to avoid overloading the server. if (!response.query) response.query = {}; if (response.watchlistraw) response.query.watchlistraw = response.watchlistraw; //adding some consistency var plist = []; if (response.query.pages) { var links; for (var id in response.query.pages) { links = response.query.pages[id].links; for (let i=0;i<links.length;i++) { plist.push(links[i].title); } } } for (var l in response.query) { if (l === 'pages') continue; for (let i=0;i<response.query[l].length;i++) { plist.push(response.query[l][i].title); } } //add the result to the pagelist immediately, as opposed to saving it all up and adding in 1 go like AWB does $('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n')); JWB.pageCount(); var cont = response.continue; console.log("Continue",JWB.pl.iterations, cont); if (cont && JWB.pl.iterations <= maxiterate) { var lists = []; if (response.query) { //compatibility with the code I wrote for the old query-continue. TODO: make this unnecessary? for (var list in response.query) { lists.push(list); //add to the new array of &list= values } } var abbrs = []; for (var abbr in cont) { data[abbr] = cont[abbr]; //add the &xxcontinue= value to the data if (abbr != 'continue') { abbrs.push(abbr.replace('continue','')); //find out what xx is and add it to the list of abbrs } } JWB.pl.getList(abbrs, lists, data); //recursive function to get every page of a list } else { if (JWB.pl.iterations > maxiterate) { JWB.status('pl-over-lim', true); } else { JWB.status('done', true); } JWB.pl.stop(); // if JWB.pl.done == true show stopped interface. Otherwise mark as done. JWB.pl.done = true; } }, function() { //on error, simply reset and let the user work with what he has JWB.status('done', true); JWB.pl.stop(); JWB.pl.done = true; }); }; JWB.pl.SMW = function(query) { var data = { action: 'ask', query: query }; JWB.api.call(data, function(response) { console.log(response); let list = response.query.results; let pagevar = response.query.printrequests[1]; let pagevar_type = pagevar && pagevar.typeid; if (pagevar) { // either pagevar === undefined, or it's the first printrequest. pagevar = pagevar.label; } let plist = []; for (let l in list) { let page = list[l]; let name = page.fulltext; let suff; if (pagevar) try { let val = page.printouts[pagevar][0]; if (!val) continue; // this page does not contain this property. switch (pagevar_type) { case '_boo': suff = val == 't'; // true if 't' else false; break; case '_wpg': suff = val.fulltext; break; case '_dat': // val.raw is also available but the unconventional format makes it a lot less convenient. suff = val.timestamp; break; case '_qty': suff = val.value + ' ' + val.unit; break; case '_mlt_rec': // I doubt this is used anywhere, but it's not too hard to support. suff = val.Text.item[0]; break; case '_ref_rec': // not supported; references contain too many properties. break; default: suff = val; } } catch(e) { console.error(e); // show error but ignore. Something is wrong in SMW query/api. } if (suff) { plist.push(name + '|' + suff); } else { plist.push(name); } } $('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n')); JWB.pageCount(); JWB.pl.stop(); // if JWB.pl.done == true show stopped interface. Otherwise mark as done. JWB.pl.done = true; }); }; //JWB.pl.getList(['wr'], ['watchlistraw'], {}) for watchlists JWB.pl.generate = function() { var $fields = $('#pagelistPopup fieldset').not('[disabled]'); $('#pagelistPopup').find('button[type="submit"]').append('<img src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="15" height="15" alt="'+JWB.msg('status-alt')+'"/>'); var abbrs = [], lists = [], data = {'continue': ''}; $fields.each(function() { var list = $(this).find('legend input').attr('name'); var abbr; if (list === 'linksto') { //Special case since this fieldset features 3 merged lists in 1 fieldset if (!$('[name="title"]').val()) return; $('[name="backlinks"], [name="embeddedin"], [name="imageusage"]').filter(':checked').each(function() { var val = this.value; abbrs.push(val); lists.push(this.name); data[val+'title'] = $('[name="title"]').val(); data[val+'filterredir'] = $('[name="filterredir"]:checked').val(); if ($('[name="redirect"]').prop('checked')) data[val+'redirect'] = true; }); } else if (list === 'smwask') { data.ask = $(this).find('#smwquery').val(); } else { //default input system if ($(this).find('#psstrict').prop('checked')) { // different list if prefixsearch is strict let $input = $(this).find('#psstrict'); list = $input.attr('name'); abbr = $input.val(); } else { abbr = $(this).find('legend input').val(); } lists.push(list); abbrs.push(abbr); $(this).find('input').not('legend input').each(function() { if ((this.type === 'checkbox' || this.type === 'radio') && this.checked === false) return; if (this.id == 'psstrict') return; // ignore psstrict; it only affects how pssearch is handled var name, val; if (this.id == 'cmtitle') { // making sure the page has a Category: prefix, in case the user left it out let cgns = JWB.ns[14]['*']; // name for Category: namespace if (!this.value.startsWith(cgns+':')) { this.value = cgns+':'+this.value; } } if (this.id == 'pssearch' && this.name == 'apprefix') { // apprefix needs namespace separate from pagename name = this.name; let split = this.value.split(':'); val = split[1] || split[0]; let nsid = 0; if (split[1]) { // if a namespace is given for (let ns in JWB.ns) { if (JWB.ns[ns]['*'] == split[0]) { nsid = JWB.ns[ns].id; break; } } } data.apnamespace = nsid; } else { name = this.name; val = this.value; } if (data.hasOwnProperty(name)) { data[name] += '|'+val; } else { data[name] = val; } }); console.log(abbrs, lists, data); } }); if (abbrs.length || data.ask) JWB.pl.getList(abbrs, lists, data); else JWB.pl.stop(); }; /***** Setup functions *****/ JWB.setup.save = function(name) { name = name || prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-store')), $('#loadSettings').val()); if (name === null) return; var self = JWB.settings[name] = { string: {}, bool: {}, replaces: [] }; //inputs with a text value $('textarea, input[type="text"], input[type="number"], select').not('.replaces input, #editBoxArea, #settings *').each(function() { if (typeof $(this).val() == 'string') { self.string[this.id] = this.value.replace(/\n{2,}/g,'\n'); } else { self.string[this.id] = $(this).val(); } }); self.replaces = []; $('.replaces').each(function() { if ($(this).find('.replaceText').val() || $(this).find('.replaceWith').val()) { self.replaces.push({ replaceText: $(this).find('.replaceText').val(), replaceWith: $(this).find('.replaceWith').val(), useRegex: $(this).find('.useRegex').prop('checked'), regexFlags: $(this).find('.regexFlags').val(), ignoreNowiki: $(this).find('.ignoreNowiki').prop('checked') }); } }); $('input[type="radio"], input[type="checkbox"]').not('.replaces input').each(function() { self.bool[this.id] = this.checked; }); if (!$('#loadSettings option[value="'+name+'"]').length) { $('#loadSettings').append('<option value="'+name+'">'+name+'</option>'); } $('#loadSettings').val(name); console.log(self); }; JWB.setup.apply = function(name) { name = name && JWB.settings[name] ? name : 'default'; var self = JWB.settings[name]; $('#loadSettings').val(name); $('.replaces + .replaces').remove(); //reset find&replace inputs $('.replaces input[type="text"]').val(''); $('.useRegex').each(function() {this.checked = false;}); $('#pagelistPopup legend input').trigger('change'); //fix checked state of pagelist generating inputs for (var a in self.string) { $('#'+a).val(self.string[a]); } for (var b in self.bool) { $('#'+b).prop('checked', self.bool[b]); } var cur; for (var c=0;c<self.replaces.length;c++) { if ($('.replaces').length <= c) $('.moreReplaces[data-insert="before"')[0].click(); cur = self.replaces[c]; for (var d in cur) { if (cur[d] === true || cur[d] === false) { $('.replaces').eq(c).find('.'+d).prop('checked', cur[d]); } else { $('.replaces').eq(c).find('.'+d).val(cur[d]); } } } JWB.listReplaces(); $('.useRegex, #containRegex,'+ '#pagelistPopup legend input,'+ '#viaJWB, #enableRETF').trigger('change'); //reset disabled inputs }; JWB.setup.getObj = function() { var settings = []; for (var i in JWB.settings) { if (i != '_blank') { settings.push('"' + i + '": ' + JSON.stringify(JWB.settings[i])); } } return '{\n\t' + settings.join(',\n\t').split('{{subst:').join('{{#JWB-SAFESUBST:#') + '\n}'; }; JWB.setup.submit = function() { var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val()); if (name === null) return; if ($.trim(name) === '') name = 'default'; JWB.setup.save(name); JWB.status('setup-submit'); JWB.api.call({ action: 'query', meta: 'tokens', }, function(response) { let edittoken = response.query.tokens.csrftoken; JWB.api.call({ title: 'User:'+JWB.username+'/'+JWB.settingspage, summary: JWB.msg(['setup-summary', JWB.contentLang]), action: 'edit', token: edittoken, text: JWB.setup.getObj(), minor: true }, function(response) { JWB.status('done', true); JWB.log('edit', response.edit.title, response.edit.newrevid); }); }); }; //TODO: use blob uri JWB.setup.download = function() { var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val()); if (name === null) return; if ($.trim(name) === '') name = 'default'; JWB.setup.save(name); JWB.status('setup-dload'); var url = 'data:application/json;base64,' + btoa(unescape(encodeURIComponent(JWB.setup.getObj()))); var elem = $('#download-anchor')[0]; if (HTMLAnchorElement.prototype.hasOwnProperty('download')) { //use download attribute when possible, for its ability to specify a filename elem.href = url; elem.click(); setTimeout(function() {elem.removeAttribute('href');}, 2000); } else { //fallback to iframes for browsers with no support for download="" attributes elem = $('#download-iframe')[0]; elem.src = url.replace('application/json', 'application/octet-stream'); setTimeout(function() {elem.removeAttribute('src');}, 2000); } JWB.status('done', true); }; JWB.setup.import = function(e) { e.preventDefault(); file = (e.dataTransfer||this).files[0]; if ($(this).is('#import')) { //reset input this.outerHTML = this.outerHTML; $('#import').change(JWB.setup.import); } if (!window.hasOwnProperty('FileReader')) { alert(JWB.msg('old-browser')); JWB.status('old-browser', '<a target="_blank" href="'+JWB.index_php+'?title=Special:MyPage/'+JWB.settingspage+'">/'+JWB.settingspage+'</a>'); return; } if (file.name.split('.').pop().toLowerCase() !== 'json') { alert(JWB.msg('not-json')); return; } JWB.status('Processing file'); var reader = new FileReader(); reader.readAsText(file); reader.onload = function(e) { JWB.status('done', true); try { //Exclusion regex based on http://stackoverflow.com/a/23589204/1256925 //Removes all JS comments from the file, except when they're between quotes. var c = reader.result; var data = JSON.parse(c.replace(/("[^"]*")|(\/\*[\w\W]*\*\/|\/\/[^\n]*)/g, function(match, g1, g2) { if (g1) return g1; })); JWB.setup.extend(data); } catch(e) { alert(JWB.msg('json-err', e.message, JWB.msg('json-err-upload'))); console.log(e); //also log the error for further info return; } }; JWB.status('Processing file'); }; JWB.setup.load = function() { JWB.status('setup-load'); var user = JWB.username||mw.config.get('wgUserName'); var oldtitle = "User:" + user + '/'+JWB.settingspage; // page title for what was used before version 4.0 var newtitle = "User:" + user + '/JWB-settings.json'; // new page title for all settings pages. var titles = oldtitle; // if the old title isn't JWB-settings.json, also query the new title. if (oldtitle !== newtitle && JWB.hasJSON) { titles += '|' + newtitle; } JWB.api.call({ action: 'query', titles: titles, prop: 'info|revisions', meta: 'tokens', rvprop: 'content', indexpageids: true }, function(response) { if (JWB === false) return; //user is not allowed to use JWB var firstrun = !JWB.setup.initialised; JWB.setup.initialised = true; var edittoken = response.query.tokens.csrftoken; // determine correct page to get settings from var pages = response.query.pages, ids = response.query.pageids; var page, exists = true; if (ids.length == 2) { var page0 = pages[ids[0]], page1 = pages[ids[1]]; var oldpage, newpage; if (page0.title == oldtitle) { oldpage = page0; newpage = page1; } else { oldpage = page1; newpage = page0; } if (oldpage.missing === undefined && oldpage.redirect === undefined) { // old page exists and is not a redirect if (newpage.missing === undefined) { // both old AND new page exist; throw error and load neither page. let jsredir = "https://www.mediawiki.org/wiki/Help:Redirects#JavaScript_page_redirect"; prompt(JWB.msg('duplicate-settings', oldtitle, newtitle, jsredir), jsredir); exists = false; } else { // old page exists but new page doesn't; move the page to the new location. JWB.setup.moveNew(oldtitle, newtitle, edittoken); JWB.settingspage = 'JWB-settings.json'; return; } } else { // Old page either doesn't exist or is a redirect. Don't bother with it. page = newpage; exists = (page.missing === undefined); JWB.settingspage = 'JWB-settings.json'; } } else { page = pages[ids[0]]; exists = (page.missing === undefined); } if (!exists) { // settings page does not exist; don't load anything if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded. return; } var data = page.revisions[0]['*'].split('{{#JWB-SAFESUBST:#').join('{{subst:'); if (!data) { // settings page is empty; don't load anything. if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded. return; } try { data = JSON.parse(data); } catch(e) { alert(JWB.msg('json-err', e.message, JWB.msg('json-err-page', JWB.settingspage)) || 'JSON error:\n'+e.message); JWB.setup.save('default'); return; } JWB.setup.extend(data); JWB.status('done', true); }); }; JWB.setup.moveNew = function(from, to, token) { var data = { action: 'move', from: from, to: to, token: token, reason: JWB.msg(['setup-move-summary', JWB.contentLang]), noredirect: true, // if possible, suppress redirects; the old page will no longer be needed if the new page exists. movesubpages: true, // if any movetalk: true, // if any ignorewarnings: true, }; if (JWB.hasTag) data.tags = 'JWB'; (new mw.Api()).post(data).done(function(response) { if (response.error === undefined) { JWB.log('move', from, to); JWB.settingspage = to.split('/')[1]; alert(JWB.msg('moved-settings', from, to, JWB.msg('tab-log'))); JWB.setup.load(); // load settings from newly moved page. } }); }; JWB.setup.extend = function(obj) { $.extend(JWB.settings, obj); if (!JWB.settings.hasOwnProperty('default')) { JWB.setup.save('default'); } for (var i in JWB.settings) { if ($('#loadSettings').find('option[value="'+i+'"]').length) continue; $('#loadSettings').append('<option value="'+i+'">'+i+'</option>'); } JWB.setup.apply($('#loadSettings').val()); }; JWB.setup.del = function() { var name = $('#loadSettings').val(); if (name === '_blank') return alert(JWB.msg('setup-delete-blank')); var temp = {}; temp[name] = JWB.settings[name]; JWB.setup.temp = $.extend({}, temp); delete JWB.settings[name]; $('#loadSettings').val('default'); if (name === 'default') { JWB.setup.apply('_blank'); JWB.setup.save('default'); JWB.status(['del-default', '<a href="javascript:JWB.setup.undelete();">'+JWB.msg('status-del-undo')+'</a>'], true); } else { $('#loadSettings').find('[value="'+name+'"]').remove(); JWB.setup.apply(); JWB.status(['del-setup', name, '<a href="javascript:JWB.setup.undelete();">'+JWB.msg('status-del-undo')+'</a>'], true); } }; JWB.setup.undelete = function() { JWB.setup.extend(JWB.setup.temp); JWB.status('done', true); }; /***** Main other functions *****/ //Show status message status-`action`, or status-`action[0]` with arguments `action[1:]` JWB.status = function(action, done) { if (JWB.bot && $('#autosave').prop('checked') && !JWB.isStopped) { $('#summary, .editbutton, #movePage, #deletePage, #protectPage, #skipPage').prop('disabled', true); //Disable summary when auto-saving } else { $('#summary, .editbutton, #movePage, #deletePage, #protectPage, #skipPage').prop('disabled', !done); //Disable box when not done (so busy loading). re-enable when done loading. } var status; if (action instanceof Array) { action[0] = 'status-'+action[0]; status = JWB.msg.apply(this, action); } else { status = JWB.msg('status-'+action); } if (status === false) return; if (status) { if (!done) { //spinner if not done status += ' <img src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="15" height="15" alt="'+JWB.msg('status-alt')+'"/>'; } } else { status = action; } $('#status').html(status); JWB.pageCount(); return action=='done'; }; JWB.pageCount = function() { if (JWB.allowed === false||!$('#articleList').length) return; $('#articleList').val(($('#articleList').val()||'').replace(/(^[ \t]*$\n)*/gm, '')); JWB.list = $('#articleList').val().split('\n'); var count = JWB.list.length; if (count === 1 && JWB.list[0] === '') count = 0; $('#totPages').html(count); }; //Generate list of replaces to be performed JWB.listReplaces = function() { JWB.replaces = []; $('.replaces').each(function() { var $this = $(this); var r = []; r[0] = $this.find('.replaceText').val() .replace(/\$x/gi, JWB.page.pagevar) // fill in pagevar .replace(/\\{2}/g, '\\').replace(/\\n/g,'\n'); // handle \n -> newline; r[1] = $this.find('.replaceWith').val(); if (r[0].length == 0 && r[1].length == 0) return; // don't bother replacing 2 empty strings. r[2] = $this.find('.regexFlags').val(); r[3] = $this; JWB.replaces.push(r); }); if (JWB.replaces.length > 1 || ( JWB.replaces.length == 1 && $('.JWBtabc .replaceText').val() == '' && $('.JWBtabc .replaceWith').val() == '' )) { // There are replace rules in the replaces popup $('#replacesButton').addClass('replacesActive'); } else { $('#replacesButton').removeClass('replacesActive'); } }; //Perform all specified find&replace actions JWB.replace = function(input, callback) { JWB.status('replacing'); if (!JWB.worker.isWorking() && JWB.worker.supported) { // if the worker is not already working, then re-init to make sure we've not got any broken leftovers from the previous page JWB.worker.init(); } JWB.newContent = input; JWB.pageCount(); var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0; JWB.page.pagevar = JWB.list[0].substr(varOffset); $.each(JWB.replaces, function(i, r) { var replaceText = r[0], replaceWith = r[1], regexFlags = r[2]; var $this = r[3]; var useRegex = replaceText.length == 0 || $this.find('.useRegex').prop('checked'); var replace = replaceText || '$'; // empty string => append (replace /$/ with text) if (useRegex && regexFlags.indexOf('_') !== -1) { replace = replace.replace(/[ _]/g, '[ _]'); //replaces any of [Space OR underscore] with a match for spaces or underscores. replace = replace.replace(/(\[[^\]]*)\[ _\]/g, '$1 _'); //in case a [ _] was placed inside another [] match, remove the []. regexFlags = regexFlags.replace('_', ''); } //apply replaces where \n and \\ work in both regular text and regex mode. var rWith = replaceWith.replace(/\$x/gi, JWB.page.pagevar).replace(/\\{2}/g, '\\').replace(/\\n/g,'\n'); if (rWith.length === 0 && replace === '$') return; try { let replaceDone = function(result, err) { console.log('done replacing', result, err); if (err === undefined) { JWB.newContent = result; if (JWB.worker.queue.length == 0 && JWB.worker.supported) { // all workers are done JWB.status('done', true); callback(JWB.newContent); } } else if (err == 'Timeout exceeded') { if (JWB.worker.queue.length == 0 && JWB.worker.supported) { // all workers have exceeded their time and/or have finished JWB.status('done', true); callback(JWB.newContent); // newContent remains unmodified due to timeout. } } }; if ($this.find('.ignoreNowiki').prop('checked')) { if (!useRegex) { replace = replace.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); regexFlags = 'g'; } JWB.worker.unparsedReplace("~"+"~~JWB.newContent", replace, regexFlags, rWith, replaceDone); } else if (useRegex) { JWB.worker.replace("~"+"~~JWB.newContent", replace, regexFlags, rWith, replaceDone); } else { JWB.newContent = JWB.newContent.split(replace).join(rWith); //global replacement without having to escape all special chars. } } catch(e) { console.log('Regex error:', e); JWB.stop(); return JWB.status('regex-err', false); } }); if ($('#enableRETF').prop('checked')) { JWB.newContent = RETF.replace(JWB.newContent); } if (!JWB.worker.isWorking()) { // no workers were called JWB.status('done', true); callback(JWB.newContent); } }; JWB.skipRETF = function() { if (!$('#enableRETF').prop('checked')) return; // RETF is not enabled to begin with if (JWB.isStopped === true) return; // don't mess with the edit box when stopped $('#enableRETF').prop('checked', false); JWB.replace(JWB.page.content, function(newContent) { JWB.editPage(newContent); JWB.updateButtons(); $('#enableRETF').prop('checked', true); }); }; // Edit the current page and pre-fill the newContent. JWB.editPage = function(newContent) { $('#editBoxArea').val(newContent); $('#currentpage').html(JWB.msg('editbox-currentpage', JWB.page.name, JWB.page.path)); if ($('#preparse').prop('checked')) { $('#articleList').val($.trim($('#articleList').val()) + '\n' + JWB.list[0]); //move current page to the bottom JWB.next(); return; } var onLoadFunctions = { diff: JWB.api.diff, preview: JWB.api.preview }; var autoSaveCallback = JWB.bot && $('#autosave').prop('checked') ? function() { //timeout will take #throttle's value * 1000, if it's a number above 0. Currently defaults to 0. setTimeout(JWB.api.submit, Math.max(+$('#throttle').val() || 0, 0) * 1000, JWB.page.name); } : null; var onLoadFunction = onLoadFunctions[$('#onLoad').val()] || onLoadFunctions.diff; onLoadFunction(autoSaveCallback); }; //Adds a line to the logs tab. JWB.log = function(action, page, info) { var d = new Date(); var pagee = encodeURIComponent(page); var extraInfo = '', actionStat = ''; switch (action) { case 'edit': if (typeof info === 'undefined') { action = 'null-edit'; actionStat = 'nullEdits'; } else { extraInfo = ' (<a target="_blank" href="'+JWB.index_php+'?title='+pagee+'&diff='+info+'">diff</a>)'; actionStat = 'pagesSaved'; } break; case 'nobots': action = 'bot-skip'; extraInfo = ' (<a target="_blank" href="https://en.wikipedia.org/wiki/Template:Bots">{{bots}}</a>)'; // no break; case 'skip': actionStat = 'pagesSkipped'; break; case 'move': extraInfo = ' to <a target="_blank" href="/wiki/'+encodeURIComponent(info)+'" title="'+info+'">'+info+'</a>'; break; case 'protect': extraInfo = info; break; } actionStat = '#' + (actionStat || 'otherActions'); $(actionStat).html(+$(actionStat).html() + 1); $('#actionlog tbody') .append('<tr>'+ '<td>'+(JWB.fn.pad0(d.getHours())+':'+JWB.fn.pad0(d.getMinutes())+':'+JWB.fn.pad0(d.getSeconds()))+'</td>'+ '<th>'+action+'</th>'+ '<td><a target="_blank" href="/wiki/'+pagee+'" title="'+page+'">'+page+'</a>'+ extraInfo +'</td>'+ '</tr>') .parents('.JWBtabc').scrollTop($('#actionlog tbody').parents('.JWBtabc')[0].scrollHeight); }; //Move to the next page in the list JWB.next = function(nextPage) { // cancel any still ongoing regex match/replace functions, since we're moving on to another page. JWB.worker.cancelAll(); if ($.trim(nextPage) && !$('#skipAfterAction').prop('checked')) { nextPage = $.trim(nextPage) + '\n'; } else { nextPage = ''; } $('#articleList').val($('#articleList').val().replace(/^.*\n?/, nextPage)); JWB.list.splice(0,1); JWB.pageCount(); JWB.api.get(JWB.list[0].split('|')[0]); }; //Stop everything, reset inputs and editor JWB.stop = function() { console.trace('stopped'); $('#stopbutton,'+ '.editbutton,'+ '#watchNow,'+ '.JWBtabc[data-tab="2"] .editbutton,'+ '#watchNow'+ '.JWBtabc[data-tab="4"] button,'+ '#skipRETF').prop('disabled', true); $('#startbutton, #articleList,'+ '.JWBtabc[data-tab="1"] button,'+ '#replacesPopup button,'+ '#replacesPopup input,'+ '.JWBtabc input, select').prop('disabled', false); $('#resultWindow').html(''); $('#editBoxArea').val(''); $('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' ')); JWB.pl.done = true; JWB.pl.stop(); JWB.status('done', true); JWB.isStopped = true; }; //Start AutoWikiBrowsing JWB.start = function() { JWB.pageCount(); JWB.listReplaces(); // generate list of replacements to make if (JWB.list.length === 0 || (JWB.list.length === 1 && !JWB.list[0])) { alert(JWB.msg('no-pages-listed')); } else if ($('#skipNoChange').prop('checked') && JWB.replaces.length === 0 && !$('#enableRETF').prop('checked')) { alert(JWB.msg('infinite-skip-notice')); } else { JWB.isStopped = false; if ($('#preparse').prop('checked')) { if (!$('#articleList').val().match('#PRE-PARSE-STOP')) { $('#articleList').val($.trim($('#articleList').val()) + '\n#PRE-PARSE-STOP'); //mark where to stop pre-parsing } } else { $('#preparse-reset').click(); } $('#stopbutton, .editbutton, #watchNow, .JWBtabc[data-tab="2"] button, .JWBtabc[data-tab="4"] button, #skipRETF').prop('disabled', false); $('#startbutton, #articleList, .JWBtabc[data-tab="1"] button, #replacesPopup button, #replacesPopup input, .JWBtabc input, select').prop('disabled', true); if (!JWB.bot || !$('#autosave').prop('checked')) { // keep summary / watchlist options enabled when not in autosave mode $('#minorEdit, #summary, #viaJWB, #watchPage').prop('disabled', false); } JWB.api.get(JWB.list[0].split('|')[0]); } }; JWB.updateButtons = function() { if (!JWB.page.exists && $('#deletePage').is('.delete')) { $('#deletePage').removeClass('delete').addClass('undelete').html(JWB.msg('editbutton-undelete')); JWB.fn.blink('#deletePage'); //Indicate the button has changed } else if (JWB.page.exists && $('#deletePage').is('.undelete')) { $('#deletePage').removeClass('undelete').addClass('delete').html(JWB.msg('editbutton-delete')); JWB.fn.blink('#deletePage'); //Indicate the button has changed } if (!JWB.page.exists) { $('#movePage').prop('disabled', true); } else { $('#movePage').prop('disabled', false); } $('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) ); }; /***** Web Worker functions *****/ JWB.worker.supported = !!window.Worker; // if window.Worker exists, we can use workers. Unless CSP blocks us. JWB.worker.queue = []; // Load function required to properly load the worker, since directly using `new Worker(url)` for cross-origin URLs does not work even with CORS/CSP rules all allowing it. // See https://stackoverflow.com/q/66188950/1256925 for this exact question JWB.worker.load = function(callback) { if (JWB.worker.blob) return callback(); // already successfully built $.getScript(JWB.imports['worker.js'], function() { // Firefox does not understand try..catch for content security policy violations, so define the worker functions regardless of the blob support. JWB.worker.functions = JWB.worker.function(); // the loaded script just defined JWB.worker.function; convert it to a blob url // Based on https://stackoverflow.com/a/33432215/1256925 if (JWB.worker.supported) try { let blob = new Blob(['('+JWB.worker.function.toString()+')()'], {type: 'text/javascript'}); JWB.worker.blob = URL.createObjectURL(blob); callback(); } catch(e) { if (e.code == 18) { JWB.worker.supported = false; } } }); }; // Create a worker to be able to preform regex operations without hanging the current process. // Based on https://stackoverflow.com/q/66153487/1256925 JWB.worker.init = function() { JWB.worker.load(function() { JWB.worker.worker = new Worker(JWB.worker.blob); JWB.worker.callback = undefined; // explicitly set to the implicit value of undefined. JWB.worker.timeout = 0; JWB.worker.queue = []; JWB.worker.worker.onmessage = function(e) { clearTimeout(JWB.worker.timeout); JWB.worker.timeout = 0; if (JWB.isStopped) { // we're stopped; clear the queue and stop. JWB.worker.queue = []; } else if (JWB.worker.callback !== undefined) { JWB.worker.callback(e.data.result, e.data.err); } else { console.error("Worker finished without callback set:", e.data, e); } JWB.worker.next(true); }; }); }; // Boolean; check if the worker is currently occupied. JWB.worker.isWorking = function() { return JWB.worker.callback !== undefined; }; // Cancel current worker's task (e.g. due to timeout) JWB.worker.terminate = function() { console.log('terminating'); let w = JWB.worker; w.worker.terminate(); w.callback(undefined, 'Timeout exceeded'); let queue = w.queue; // save old queue w.init(); // re-init this worker, since the previous one is presumed dead (and terminated). w.queue = queue; // restore queue }; // Cancel all workers (e.g. due to no longer needing the worker's queued services) JWB.worker.cancelAll = function() { JWB.worker.queue = []; if (JWB.worker.worker) JWB.worker.worker.terminate(); // do not call the callback. }; // Set worker to work, or queue the worker task. JWB.worker.do = function(msg, callback) { if (JWB.worker.isWorking()) { JWB.worker.queue.push({msg: msg, callback: callback}); } else { var timelimit = parseInt($('#timelimit').val()) || 3000; JWB.worker.callback = callback; // Expand "JWB.string" into JWB['string']; to allow the string to be loaded at execution time instead of queue time. // Start with 3x ~ because that cannot exist as the start of an actual page if (msg.str && msg.str.indexOf('~'+'~~JWB.') === 0) msg.str = JWB[msg.str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.worker.postMessage(msg); JWB.worker.timeout = setTimeout(function() { if (!JWB.worker.isWorking()) { console.error('Worker error'); JWB.worker.next(true); return; } JWB.worker.terminate(); JWB.worker.next(true); }, timelimit); } }; // Execute the next task in the queue JWB.worker.next = function(force = false) { if (force) { // force means the function that's calling next() has handled the previous worker task. Clean up after it. JWB.worker.callback = undefined; } else if (JWB.worker.isWorking()) { // still working and the calling function did not specify proper exit of the previous task yet. return false; } if (JWB.worker.queue.length === 0) return true; var q = JWB.worker.queue.shift(); JWB.worker.do(q.msg, q.callback); }; /***** Functions using workers *****/ JWB.worker.match = function(str, pattern, flags, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'match', str, pattern, flags}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.match(str, pattern, flags, callback); } }; JWB.worker.replace = function(str, pattern, flags, rWith, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'replace', str, pattern, flags, rWith}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.replace(str, pattern, flags, rWith, callback); } }; JWB.worker.unparsedReplace = function(str, pattern, flags, rWith, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'unparsedreplace', str, pattern, flags, rWith}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.unparsedreplace(str, pattern, flags, rWith, callback); } }; /***** General functions *****/ //Clear all existing timers to prevent them from getting errors JWB.fn.clearAllTimeouts = function() { var i = setTimeout(function() { return void(0); }, 1000); for (var n=0;n<=i;n++) { clearTimeout(n); clearInterval(n); } console.log('Cleared all running intervals up to index',i); }; //Filter an array to only contain unique values. JWB.fn.uniques = function(arr) { var a = []; for (var i=0, l=arr.length; i<l; i++) { if (a.indexOf(arr[i]) === -1 && arr[i] !== '') { a.push(arr[i]); } } return a; }; // code taken directly from [[Template:Bots]] and changed structurally (not functionally) for readability. The user in this case is "JWB" to deny this script. // the user parameter is still kept as an optional parameter to maintain functionality as given on that template page. JWB.fn.allowBots = function(text, user = "JWB") { var usr = user.replace(/([\(\)\*\+\?\.\-\:\!\=\/\^\$])/g, "\\$1"); if (!new RegExp("\\{\\{\\s*(nobots\\s*\\}\\}|bots\\s*(?:\\}\\}|\\|))", "i").test(text)) return true; if (new RegExp("\\{\\{\\s*bots\\s*\\|\\s*deny\\s*=\\s*([^}]*,\\s*)*" + usr + "\\s*(?=[,\\}])[^}]*\\s*\\}\\}", "i").test(text)) return false; else return new RegExp("\\{\\{\\s*((?!nobots)|bots(\\s*\\|\\s*allow\\s*=\\s*((?!none)|([^}]*,\\s*)*" + usr + "\\s*(?=[,\\}])[^}]*|all))?|bots\\s*\\|\\s*deny\\s*=\\s*(?!all)[^}]*|bots\\s*\\|\\s*optout=(?!all)[^}]*)\\s*\\}\\}", "i").test(text); }; //Prepends zeroes until the number has the desired length of len (default 2) JWB.fn.pad0 = function(n, len = 2) { n = n.toString(); return n.length < len ? Array(len-n.length+1).join('0')+n : n; }; JWB.fn.blink = function(el,t) { t=t?t:500; $(el).prop('disabled', true) .children().animate({opacity:'0.1'},t-100) .animate({opacity:'1'},t) .animate({opacity:'0.1'},t-100) .animate({opacity:'1'},t); setTimeout("$('"+el+"').prop('disabled', false)",t*4-400); }; JWB.fn.setSelection = function(el, start, end, dir) { dir = dir||'none'; //Default value end = end||start; //If no end is specified, assume the caret is placed without creating text selection. if (el.setSelectionRange) { el.focus(); el.setSelectionRange(start, end, dir); } else if (el.createTextRange) { var rng = el.createTextRange(); rng.collapse(true); rng.moveStart('character', start); rng.moveEnd('character', end); rng.select(); } }; JWB.fn.scrollSelection = function(el, index) { //function to fix scrolling to selection - doesn't do that automatically. var newEl = document.createElement('textarea'); //create a new textarea to simulate the same conditions var elStyle = getComputedStyle(el); newEl.style.height = elStyle.height; //copy over size-influencing styles newEl.style.width = elStyle.width; newEl.style.lineHeight = elStyle.lineHeight; newEl.style.fontSize = elStyle.fontSize; newEl.value = el.value.substr(0,index); document.body.appendChild(newEl); //needs to be added to the HTML for the scrollHeight and clientHeight to work. if (newEl.scrollHeight != newEl.clientHeight) { el.scrollTop = newEl.scrollHeight - 2; } else { el.scrollTop = 0; } newEl.remove(); //clean up the mess I've made }; //i18n function JWB.msg = function(message) { var args = arguments; var lang = JWB.lang; if (typeof message === 'object') { lang = message[1]; message = message[0]; } if (lang == 'qqx') return message; if (!JWB.messages || !JWB.messages.en) return '\u29FC'+message+'\u29FD'; // same surrounding <> as used in mw.msg(); var msg; if (JWB.messages.hasOwnProperty(lang) && JWB.messages[lang].hasOwnProperty(message)) { msg = JWB.messages[lang][message]; } else { msg = (JWB.messages.en.hasOwnProperty(message)) ? JWB.messages.en[message] : '\u29FC'+message+'\u29FD'; } msg = msg.replace(/\$(\d+)/g, function(match, num) { return args[+num] || match; }); return msg; }; /***** Init *****/ // Check whether or not we are ready to init JWB. If not allowed, abort and delete JWB object to deny access. JWB.checkInit = function() { if (JWB.allowed === false) { var msg = JWB.msg('not-on-list'); JWB = false; delete JWB; alert(msg); return; } JWB.allLoaded = true; for (var m in JWB.messages) if (JWB.messages[m] === null) JWB.allLoaded = false; if (JWB.allowed === true && JWB.allLoaded && Object.keys(JWB.messages).length == JWB.langs.length + 1) { // if there are two languages to load, wait for them both. console.log('langs loaded'); JWB.init(); //init if verification has already returned true } }; // Initialise JWB JWB.init = function() { console.log(JWB.messages.en, !!JWB.messages.en); JWB.setup.load(); JWB.worker.init(); JWB.fn.clearAllTimeouts(); var findreplace = '<div class="replaces">'+ '<label style="display:block;">'+JWB.msg('label-replace')+' <input type="text" class="replaceText"/></label>'+ '<label style="display:block;">'+JWB.msg('label-rwith')+' <input type="text" class="replaceWith"/></label>'+ '<div class="regexswitch">'+ '<label><input type="checkbox" class="useRegex"> '+JWB.msg('label-useregex')+'</label>'+ '<a class="infoLink" href="http://regex101.com/#javascript" target="_blank" tabindex="-1">101</a>'+ '<label class="divisor" title="'+JWB.msg('tip-regex-flags')+'" style="display:none;">'+ JWB.msg('label-regex-flags')+' <input type="text" class="regexFlags" value="g"/>'+ //default: global replacement '</label>'+ '<br/>'+ '</div>'+ '<label title="'+JWB.msg('tip-ignore-comment')+'">'+ '<input type="checkbox" class="ignoreNowiki"> '+JWB.msg('label-ignore-comment')+ '</label>'+ '</div>'; var NSList = '<select multiple name="namespace" id="namespacelist">'; for (var i in JWB.ns) { if (parseInt(i) < 0) continue; //No Special: or Media: in the list NSList += '<option value="'+JWB.ns[i].id+'" selected>'+(JWB.ns[i]['*'] || '('+JWB.msg('namespace-main')+')')+'</option>'; } NSList += '</select>'; /***** Interface *****/ document.title = 'AutoWikiBrowser Script'+(document.title.split('-')[1] ? ' -'+document.title.split('-')[1] : ''); $('body').html( '<article id="resultWindow"></article>'+ '<main id="inputsWindow">'+ '<div id="inputsBox">'+ '<aside id="articleBox">'+ '<b>'+JWB.msg('pagelist-caption')+'</b>'+ '<textarea id="articleList"></textarea>'+ '</aside>'+ '<section id="tabs">'+ '<nav class="tabholder">'+ '<span class="JWBtab active" data-tab="1">'+JWB.msg('tab-setup')+'</span> '+ '<span class="JWBtab" data-tab="2">'+JWB.msg('tab-editing')+'</span> '+ '<span class="JWBtab" data-tab="3">'+JWB.msg('tab-skip')+'</span> '+ (JWB.sysop?'<span class="JWBtab" data-tab="4">'+JWB.msg('tab-other')+'</span> ':'')+ ' <span class="JWBtab log" data-tab="5">'+JWB.msg('tab-log')+'</span> '+ '</nav>'+ '<section class="JWBtabc active" data-tab="1"></section>'+ '<section class="JWBtabc" data-tab="2"></section>'+ '<section class="JWBtabc" data-tab="3"></section>'+ (JWB.sysop?'<section class="JWBtabc" data-tab="4"></section>':'')+ '<section class="JWBtabc log" data-tab="5"></section>'+ '<footer id="status">done</footer>'+ '</section>'+ '<aside id="editBox">'+ '<b>'+JWB.msg('editbox-caption')+' - <span id="currentpage">'+JWB.msg('editbox-currentpage', ' ', ' ')+'</span></b>'+ '<textarea id="editBoxArea" accesskey=","></textarea>'+ '</aside>'+ '</div>'+ '</main>'+ '<footer id="stats">'+ JWB.msg('stat-pages')+' <span id="totPages">0</span>;&emsp;'+ JWB.msg('stat-save')+' <span id="pagesSaved">0</span>;&emsp;'+ JWB.msg('stat-null')+' <span id="nullEdits">0</span>;&emsp;'+ JWB.msg('stat-skip')+' <span id="pagesSkipped">0</span>;&emsp;'+ JWB.msg('stat-other')+' <span id="otherActions">0</span>;&emsp;'+ '</footer>'+ '<div id="overlay" style="display:none;"></div>'+ '<section class="JWBpopup" id="replacesPopup" style="display:none;">'+ '<button class="moreReplaces" data-insert="after">'+JWB.msg('button-more-fields')+'</button>'+ '<br>'+findreplace+ '<button class="moreReplaces" data-insert="before">'+JWB.msg('button-more-fields')+'</button>'+ '</section>'+ '<section class="JWBpopup" id="pagelistPopup" style="display:none;">'+ '<form action="#" id="pl-form"></form>'+ '</section>' ); $('.JWBtabc[data-tab="1"]').html( '<fieldset id="pagelist">'+ '<legend>'+JWB.msg('label-pagelist')+'</legend>'+ '<button id="removeDupes">'+JWB.msg('button-remove-dupes')+'</button> '+ '<button id="sortArticles">'+JWB.msg('button-sort')+'</button>'+ '<br>'+ '<label title="'+JWB.msg('tip-preparse')+'">'+ '<input type="checkbox" id="preparse"> '+JWB.msg('preparse')+ '</label>'+ '<span class="divisor"></span>'+ '<button id="preparse-reset" title="'+JWB.msg('tip-preparse-reset')+'">'+JWB.msg('preparse-reset')+'</button>'+ '<br>'+ '<button id="pagelistButton">'+JWB.msg('pagelist-generate')+'</button>'+ '</fieldset>'+ '<fieldset id="settings">'+ '<legend>'+JWB.msg('label-settings')+'</legend>'+ '<button id="saveAs" title="'+JWB.msg('tip-store-setup')+'">'+JWB.msg('store-setup')+'</button>'+ '<br>'+ '<label>'+ JWB.msg('load-settings') + ' '+ '<select id="loadSettings">'+ '<option value="default" selected>default</option>'+ '<option value="_blank">'+JWB.msg('blank-setup')+'</option>'+ '</select>'+ '</label>'+ '<span class="divisor"></span>'+ '<button id="deleteSetup" title="'+JWB.msg('tip-delete-setup')+'">'+JWB.msg('delete-setup')+'</button>'+ '<hr>'+ '<button id="saveToWiki">'+JWB.msg('save-setup')+'</button>'+ '<span class="divisor"></span>'+ '<button id="download">'+JWB.msg('download-setup')+'</button>'+ '<hr>'+ '<label class="button" id="importLabel" title="'+JWB.msg('tip-import-setup')+'">'+ '<input type="file" id="import" accept=".json">'+ JWB.msg('import-setup')+ '</label>'+ '<span class="divisor"></span>'+ '<button id="updateSetups" title="'+JWB.msg('tip-update-setup', JWB.settingspage)+'">'+JWB.msg('update-setup')+'</button>'+ '<div id="downloads">'+ '<a download="JWB-settings.json" target="_blank" id="download-anchor"></a>'+ '<iframe id="download-iframe"></iframe>'+ '</div>'+ '</fieldset>'+ '<fieldset id="limits">'+ '<legend>'+JWB.msg('label-limits')+'</legend>'+ '<label class="timelimit-label" title="'+JWB.msg('tip-time-limit')+'">'+ JWB.msg('time-limit')+ '<input type="number" id="timelimit" value="3000" min="0">'+ '</label>'+ '<label title="'+JWB.msg('tip-diff-size-limit')+'">'+ JWB.msg('diff-size-limit')+ '<input type="number" id="sizelimit" value="0" min="0">'+ '</label>'+ '</fieldset>' ); $('.JWBtabc[data-tab="2"]').html( '<label class="minorEdit"><input type="checkbox" id="minorEdit" accesskey="i" checked> '+JWB.msg('minor-edit')+'</label>'+ '<label class="editSummary'+(JWB.hasTag?'':' viaJWB')+'">'+JWB.msg('edit-summary')+'<br/> <input class="fullwidth" type="text" id="summary" maxlength="500" accesskey="b"></label>'+ ' <input type="checkbox" id="viaJWB"'+(JWB.hasTag?'':' checked')+' title="'+JWB.msg('tip-via-JWB')+'">'+ '<select id="watchPage">'+ '<option value="watch">'+JWB.msg('watch-watch')+'</option>'+ '<option value="unwatch">'+JWB.msg('watch-unwatch')+'</option>'+ '<option value="nochange" selected>'+JWB.msg('watch-nochange')+'</option>'+ '<option value="preferences">'+JWB.msg('watch-preferences')+'</option>'+ '</select>'+ '<span class="divisor"></span>'+ '<button id="watchNow" disabled accesskey="w">'+ JWB.msg('watch-add')+ '</button>'+ '<br>'+ (JWB.bot? '<label><input type="checkbox" id="autosave"> '+JWB.msg('auto-save')+'</label>'+ '<label title="'+JWB.msg('tip-save-interval')+'" class="divisor">'+ JWB.msg('save-interval', '<input type="number" min="0" value="0" style="width:50px" id="throttle" disabled>')+ '</label>'+ '<br>' :'')+ '<label style="display:block">'+ JWB.msg('on-load')+ ' <select id="onLoad">'+ '<option value="diff" selected>'+JWB.msg('on-load-diff')+'</option>'+ '<option value="preview">'+JWB.msg('on-load-preview')+'</option>'+ '</select>'+ '</label>'+ '<hr>'+ '<span id="startstop">'+ '<button id="startbutton" accesskey="a">'+JWB.msg('editbutton-start')+'</button>'+ '<br>'+ '<button id="stopbutton" disabled accesskey="q">'+JWB.msg('editbutton-stop')+'</button> '+ '</span>'+ '<button class="editbutton" id="skipButton" disabled accesskey="n">'+JWB.msg('editbutton-skip')+'</button>'+ '<button class="editbutton" id="submitButton" disabled accesskey="s">'+JWB.msg('editbutton-save')+'</button>'+ '<br>'+ '<button class="editbutton" id="previewButton" disabled accesskey="p">'+JWB.msg('editbutton-preview')+'</button>'+ '<button class="editbutton" id="diffButton" disabled accesskey="d">'+JWB.msg('editbutton-diff')+'</button>'+ '<button id="replacesButton">'+JWB.msg('button-open-popup')+'</button>'+ findreplace+ '<hr>'+ '<label><input type="checkbox" id="enableRETF"> '+ JWB.msg('label-enable-RETF', '<a href="/wiki/Project:AutoWikiBrowser/Typos" target="_blank">'+ JWB.msg('label-RETF')+ '</a>')+ '</label>'+ ' <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Gnome-view-refresh.svg/20px-Gnome-view-refresh.svg.png"'+ 'id="refreshRETF" title="'+JWB.msg('tip-refresh-RETF')+'">'+ '<br/>'+ '<button id="skipRETF" title="'+JWB.msg('tip-skip-RETF')+'" disabled>'+JWB.msg('skip-RETF')+'</button>' ); $('.JWBtabc[data-tab="3"]').html( '<fieldset>'+ '<legend>'+JWB.msg('label-redirects')+'</legend>'+ '<label title="'+JWB.msg('tip-redirects-follow')+'">'+ '<input type="radio" class="redirects" value="follow" name="redir" id="redir-follow"> '+JWB.msg('redirects-follow')+' '+ '</label>'+ '<label title="'+JWB.msg('tip-redirects-skip')+'">'+ '<input type="radio" class="redirects" value="skip" name="redir" id="redir-skip"> '+JWB.msg('redirects-skip')+' '+ '</label>'+ '<label title="'+JWB.msg('tip-redirects-edit')+'">'+ '<input type="radio" class="redirects" value="edit" name="redir" id="redir-edit" checked> '+JWB.msg('redirects-edit')+''+ '</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('label-skip-when')+'</legend>'+ '<label><input type="checkbox" id="skipNoChange"> '+JWB.msg('skip-no-change')+'</label>'+ '<br>'+ '<label><input type="radio" id="exists-yes" name="exists" value="yes"> '+JWB.msg('skip-exists-yes')+'</label> '+ '<label><input type="radio" id="exists-no" name="exists" value="no" checked> '+JWB.msg('skip-exists-no')+'</label> '+ '<label><input type="radio" id="exists-neither" name="exists" value="neither"> '+JWB.msg('skip-exists-neither')+'</label>'+ (JWB.sysop?'<br><label><input type="checkbox" id="skipAfterAction" checked> '+JWB.msg('skip-after-action')+'</label>':'')+ '<hr/>'+ '<label>'+JWB.msg('skip-contains')+' <input class="fullwidth" type="text" id="skipContains"></label>'+ '<label>'+JWB.msg('skip-not-contains')+' <input class="fullwidth" type="text" id="skipNotContains"></label>'+ '<div class="regexswitch">'+ '<label><input type="checkbox" id="containRegex"> '+JWB.msg('label-useregex')+'</label>'+ '<a class="re101" href="http://regex101.com/#javascript" target="_blank">?</a>'+ '<label class="divisor" title="'+JWB.msg('tip-regex-flags')+'" style="display:none;">'+ JWB.msg('label-regex-flags')+' <input type="text" id="containFlags"/>'+ '</label>'+ '</div>'+ '<hr/>'+ '<label title="'+JWB.msg('skip-cg-prefix')+'">'+JWB.msg('skip-category')+' <input class="fullwidth" type="text" id="skipCategories"></label>'+ '</fieldset>' ); if (JWB.sysop) $('.JWBtabc[data-tab="4"]').html( '<fieldset>'+ '<legend>'+JWB.msg('move-header')+'</legend>'+ '<label><input type="checkbox" id="suppressRedir"> '+JWB.msg('move-redir-suppress')+'</label>'+ '<br>'+ JWB.msg('move-also')+' '+ '<label><input type="checkbox" id="movetalk"> '+JWB.msg('move-talk-page')+'</label> '+ '<label><input type="checkbox" id="movesubpage"> '+JWB.msg('move-subpage')+'</label>'+ '<br>'+ '<label>'+JWB.msg('move-new-name')+' <input type="text" id="moveTo"></label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('delete-header')+'</legend>'+ '<label><input type="checkbox" id="deleteTalk"> '+JWB.msg('delete-talk')+'</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('protect-header')+'</legend>'+ JWB.msg('protect-edit')+ ' <select id="editProt">'+ '<option value="all" selected>'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ JWB.msg('protect-move')+ ' <select id="moveProt">'+ '<option value="" selected>('+JWB.msg('protect-like-edit')+')</option>'+ '<option value="all">'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ JWB.msg('protect-upload')+ ' <select id="uploadProt">'+ '<option value="" selected>('+JWB.msg('protect-like-edit')+')</option>'+ '<option value="all">'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ '<label>'+JWB.msg('protect-expiry')+'<a class="infoLink" href="https://www.mediawiki.org/w/api.php?action=help&modules=main#main/datatypes" target="_blank" tabindex="-1">?</a> <input type="text" id="protectExpiry"/></label>'+ '</fieldset>'+ '<button id="movePage" disabled accesskey="m">'+JWB.msg('editbutton-move')+'</button> '+ '<button id="deletePage" class="delete" disabled accesskey="x">'+JWB.msg('editbutton-delete')+'</button> '+ '<button id="protectPage" disabled accesskey="z">'+JWB.msg('editbutton-protect')+'</button> '+ '<button id="skipPage" disabled title="['+JWB.tooltip+'n]">'+JWB.msg('editbutton-skip')+'</button>'+ '<div class="logActionNote">'+JWB.msg('log-action-note')+'</div>' ); $('.JWBtabc[data-tab="5"]').html('<table id="actionlog"><tbody></tbody></table>'); $('#pagelistPopup form').html( '<div id="ns-filter" title="'+JWB.msg('tip-ns-select')+'">' + JWB.msg('label-ns-select') + NSList + '</div>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="categorymembers" name="categorymembers" value="cm"> '+JWB.msg('legend-cm')+'</label></legend>'+ '<label title="'+JWB.msg('tip-cm')+'">'+JWB.msg('label-cm')+' <input type="text" name="cmtitle" id="cmtitle" class="fullwidth"></label>'+ '<div>'+JWB.msg('cm-include')+' '+ '<label><input type="checkbox" id="cmtype-page" name="cmtype" value="page" checked> '+JWB.msg('cm-include-pages')+'</label>'+ '<label><input type="checkbox" id="cmtype-subcg" name="cmtype" value="subcat" checked> '+JWB.msg('cm-include-subcgs')+'</label>'+ '<label><input type="checkbox" id="cmtype-file" name="cmtype" value="file" checked> '+JWB.msg('cm-include-files')+'</label>'+ '</div>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" name="linksto" id="linksto"> '+JWB.msg('legend-linksto')+'</label></legend>'+ '<label>'+JWB.msg('label-linksto')+' <input type="text" name="title" id="linksto-title" class="fullwidth"></label>'+ '<div>'+JWB.msg('links-include')+' '+ '<label><input type="checkbox" id="backlinks" name="backlinks" value="bl" checked> '+JWB.msg('links-include-links')+'</label>'+ '<label><input type="checkbox" id="embeddedin" name="embeddedin" value="ei"> '+JWB.msg('links-include-templ')+'</label>'+ '<label><input type="checkbox" id="imageusage" name="imageusage" value="iu"> '+JWB.msg('links-include-files')+'</label>'+ '</div>'+ '<div>'+JWB.msg('links-redir')+' '+ '<label><input type="radio" id="rfilter-redir" name="filterredir" value="redirects"> '+JWB.msg('links-redir-redirs')+'</label>'+ '<label><input type="radio" id="rfilter-nonredir" name="filterredir" value="nonredirects"> '+JWB.msg('links-redir-noredirs')+'</label>'+ '<label><input type="radio" id="rfilter-all" name="filterredir" value="all" checked> '+JWB.msg('links-redir-all')+'</label>'+ '</div>'+ '<label title="'+JWB.msg('tip-link-redir')+'">'+ '<input type="checkbox" name="redirect" value="true" checked id="linksto-redir"> '+JWB.msg('label-link-redir')+ '</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="prefixsearch" name="prefixsearch" value="ps"> '+JWB.msg('legend-ps')+'</label></legend>'+ '<label>'+JWB.msg('label-ps')+' <input type="text" name="pssearch" id="pssearch" class="fullwidth"></label>'+ '<label title="'+JWB.msg('tip-ps-strict')+'"><input type="checkbox" name="allpages" value="ap" id="psstrict" checked> '+JWB.msg('label-ps-strict')+'</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="watchlistraw" name="watchlistraw" value="wr"> '+JWB.msg('legend-wr')+'</label></legend>'+ JWB.msg('label-wr')+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="proplinks" name="links" value="pl"> '+JWB.msg('legend-pl')+'</label></legend>'+ '<label title="'+JWB.msg('tip-pl')+'">'+JWB.msg('label-pl')+' <input type="text" id="titles" name="titles" class="fullwidth"></label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="proplinks" name="search" value="sr"> '+JWB.msg('legend-sr')+'</label></legend>'+ '<label title="'+JWB.msg('tip-sr')+'\n'+JWB.msg('placeholder-sr', 'insource:', 'intitle:')+'">'+ JWB.msg('label-sr')+ ' <input type="text" id="srsearch" name="srsearch" class="fullwidth" placeholder="'+JWB.msg('placeholder-sr', 'insource:', 'intitle:')+'">'+ '</label>'+ '</fieldset>'+ '<fieldset class="listSMW">'+ '<legend><label><input type="checkbox" id="smwask" name="smwask" value="smw"> '+JWB.msg('legend-smw', JWB.msg('smw-slow'))+'</label></legend>'+ '<textarea id="smwquery" name="smwquery" placeholder="'+JWB.msg('label-smw', '\n|limit=500')+'"></textarea>'+ '</fieldset>'+ '<button type="submit">'+JWB.msg('pagelist-generate')+'</button>' ); if (JWB.hasSMW) { $('#pagelistPopup').addClass('hasSMW'); } $('body').addClass('AutoWikiBrowser').addClass('notheme'); //allow easier custom styling of JWB. $('[accesskey]').each(function() { let lbl = this.accessKeyLabel || this.accessKey; // few browsers support accessKeyLabel, so fallback to accessKey. $(this).attr('title', '['+lbl+']'); }); /***** Setup *****/ JWB.setup.save('_blank'); //default setup if (JWB.settings.hasOwnProperty('default')) { JWB.setup.apply(); } else if (JWB.setup.initialised) { // If we already initialised, create the default settings profile. JWB.setup.save('default'); } JWB.setup.extend({}); /***** Event handlers *****/ //Alert user when leaving the tab, to prevent accidental closing. onbeforeunload = function() { return "Closing this tab will cause you to lose all progress."; }; ondragover = function(e) { e.preventDefault(); }; document.addEventListener("securitypolicyviolation", function(e) { console.log('violated CSP:', e); if (e.blockedURI == 'blob') { JWB.worker.supported = false; // tell the next JWB.worker.init() that it shouldn't even try. } else if (JWB && JWB.msg) { alert(JWB.msg('csp-error', e.violatedDirective)); } }); $('.JWBtab').click(function() { $('.active').removeClass('active'); $(this).addClass('active'); $('.JWBtabc[data-tab="'+$(this).attr('data-tab')+'"]').addClass('active'); }); function showRegexFlags() { // >>this<< is the element that's triggered $(this).parent().nextAll('label').toggle(this.checked); } $('body').on('change', '#useRegex, #containRegex, .useRegex', showRegexFlags); $('#preparse-reset').click(function() { $('#articleList').val($('#articleList').val().replace(/#PRE-PARSE-STOP/g,'').replace(/\n\n/g, '\n')); }); $('#saveAs').click(function() { JWB.setup.save(); }); $('#loadSettings').change(function() { JWB.setup.apply(this.value); }); $('#download').click(JWB.setup.download); $('#saveToWiki').click(JWB.setup.submit); $('#import').change(JWB.setup.import); ondrop = JWB.setup.import; $('#updateSetups').click(JWB.setup.load); $('#deleteSetup').click(JWB.setup.del); if (window.RETF) { $('#refreshRETF').click(RETF.load); $('#skipRETF').click(JWB.skipRETF); $('#enableRETF').change(function() { $('#skipRETF').css('visibility', this.checked ? 'visible' : 'hidden'); }); } $('#replacesButton, #pagelistButton').click(function() { var popup = this.id.slice(0, -6); //omits the 'Button' in the id by cutting off the last 6 characters $('#'+popup+'Popup, #overlay').show(); }); $('#overlay').click(function() { $('#replacesPopup, #pagelistPopup, #overlay').hide(); JWB.listReplaces(); JWB.pl.done = true; JWB.pl.stop(); }); $('.moreReplaces').click(function() { var location = $(this).data('insert'); // either call $(this).before() or $(this).after() $(this)[location](findreplace); }); $('#replacesPopup').on('keydown', '.replaces:last', function(e) { if (e.which === 9) $('.moreReplaces[data-insert="before"]')[0].click(); }); $('#pl-form').submit(function(e) { e.preventDefault(); JWB.pl.generate(); return false; }); $('#pagelistPopup legend input').change(function() { //remove disabled attr when checked, add when not. $(this).parents('fieldset').find('input').not('legend input').prop('disabled', !this.checked); $(this).parents('fieldset').prop('disabled', !this.checked); }).trigger('change'); $('#psstrict').change(function() { if (this.checked) { $('#pssearch').attr('name', 'apprefix'); } else { $('#pssearch').attr('name', 'pssearch'); } }).trigger('change'); $('#resultWindow').on('click', 'tr[data-line]:not(.lineheader) *', function(e) { var line = +$(e.target).closest('tr[data-line]').data('line'); var index = $('#editBoxArea').val().split('\n').slice(0, line-1).join('\n').length; $('#editBoxArea')[0].focus(); JWB.fn.setSelection($('#editBoxArea')[0], index+1); JWB.fn.scrollSelection($('#editBoxArea')[0], index); }); $('#removeDupes').click(function() { $('#articleList').val(JWB.fn.uniques($('#articleList').val().split('\n')).join('\n')); JWB.pageCount(); }); $('#sortArticles').click(function() { $('#articleList').val($('#articleList').val().split('\n').sort().join('\n')); JWB.pageCount(); }); $('#watchNow').click(JWB.api.watch); $('#autosave').change(function() { $('#throttle').prop('disabled', !this.checked); }); $('#viaJWB').change(function() { $('#summary').parent('label') .toggleClass('viaJWB', this.checked) .attr('maxlength', 500 - this.checked*JWB.summarySuffix.length); // Change the max size of the allowed summary according to having a suffix or not. }); $('#startbutton').click(JWB.start); $('#stopbutton').click(JWB.stop); $('#submitButton').click(JWB.api.submit); $('#previewButton').click(JWB.api.preview); $('#diffButton').click(JWB.api.diff); $('#skipButton, #skipPage').click(function() { JWB.log('skip', JWB.list[0].split('|')[0]); JWB.next(); }); if (JWB.sysop) { $('#movePage').click(function() { if ($('#moveTo').val().length === 0) { return alert(JWB.msg('alert-no-move')); } JWB.api.move(); }); $('#protectPage').click(JWB.api.protect); $('#deletePage').click(JWB.api.del); } }; //Disable JWB altogether when it's loaded on a page other than Project:AutoWikiBrowser/Script. This script shouldn't be loaded on any other page in the first place. if (JWB.allowed === false) JWB = false; /* JWB sonu */ eypbeyecbh20a9eawyjr1q7a8zkyyyh 240643 240632 2026-10-16T18:45:55Z Brightt11 34669 [[Kullanıcı:Brightt11|Brightt11]] ([[Özel:Contributions/Brightt11|k]]-[[Kullanıcı mesaj:Brightt11|m]]-[[Özel:Blockip/Brightt11|e]]) tarafından yapılan 240632 sayılı değişiklik geri alınıyor. 240643 javascript text/javascript /* who is active başlangıcı */ $( function () { const filteredLinks = []; const localizedUserNamespace = mw.config.get( 'wgFormattedNamespaces' )[2]; $( '.mw-parser-output' ). find( 'a[title^="User:"], a[title^="' + localizedUserNamespace + ':"]' ). each( function() { const link = $( this ); const href = decodeURI( link.attr( 'href' ) ); const userRegex = new RegExp( '((User)|(' + localizedUserNamespace + ')):(.*?)(?=&|$)' ); const username = href.match(userRegex); const index = username[0].indexOf( '/' ); if ( username[0].indexOf( '/' ) === -1 ) { filteredLinks.push( { username: username[0], element: link } ); } } ); if ( !filteredLinks.length ) { return; } const RECENT = 'recent'; const THISYEAR = 'thisyear'; const OVERAYEAR = 'overayear'; const messages = { en: { recent: 'Edited recently', thisyear: 'Edited this year', overayear: 'Edited over a year ago' }, tr: { recent: 'Aktif', thisyear: 'Yarı aktif', overayear: 'Aktif değil' }, de: { recent: 'kürzlich bearbeitet', thisyear: 'in diesem Jahr bearbeitet', overayear: 'vor über einem Jahr bearbeitet' } }; const localizedMessages = function () { const lang = mw.config.get( 'wgUserLanguage' ); if ( lang in messages ) { return messages[lang]; } return messages.en; }(); const getLastActiveMarker = function ( timestamp ) { const date = Date.parse( timestamp ); const now = Date.now(); const diff = Math.floor( ( now - date ) / ( 1000 * 60 * 60 * 24 ) ); var timespan = RECENT; if ( diff > 365 ) { timespan = OVERAYEAR; } else if ( diff > 15 ) { timespan = THISYEAR; } const iconPath = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/resources/lib/ooui/themes/wikimediaui/images/icons/userContributions-ltr.svg'; const marker = "<span class='mw-whoisactivegadget-span mw-whoisactivegadget-" + timespan + "'>" + "<img src='" + iconPath + "' class='mw-whoisactivegadget-filter-" + timespan + "'/> " + localizedMessages[timespan] + "<span>"; return $( marker ); }; mw.loader.using( [ 'mediawiki.api' ], function () { filteredLinks.forEach( function( item ) { const username = item.username; const element = item.element; const api = new mw.Api(); api.get( { format: 'json', action: 'query', list: 'usercontribs', uclimit: '1', ucuser: username } ).then( function ( result ) { if ( result.query.usercontribs.length ) { const timestamp = result.query.usercontribs[0].timestamp; getLastActiveMarker( timestamp ).insertAfter( element ); } } ); } ); } ); } ); /*who is active sonu*/ /* twinkle başlangıcı /* /** * +-------------------------------------------------------------------------+ * | === WARNING: GLOBAL GADGET FILE === | * | Changes to this page affect many users. | * | Please discuss changes at [[WT:TW]] before editing. | * +-------------------------------------------------------------------------+ * * Imported from github [https://github.com/wikimedia-gadgets/twinkle]. * All changes should be made in the repository, otherwise they will be lost. * * ---------- * * This is AzaToth's Twinkle, the popular script sidekick for newbies, admins, and * every Wikipedian in between. Visit [[WP:TW]] for more information. */ // <nowiki> /* global Morebits */ (function() { // Check if account is experienced enough to use Twinkle if (!Morebits.userIsInGroup('autoconfirmed') && !Morebits.userIsInGroup('confirmed')) { return; } const Twinkle = {}; window.Twinkle = Twinkle; // allow global access Twinkle.initCallbacks = []; /** * Adds a callback to execute when Twinkle has loaded. * * @param {Function} func * @param {string} [name] - name of module used to check if is disabled. * If name is not given, module is loaded unconditionally. */ Twinkle.addInitCallback = function twinkleAddInitCallback(func, name) { Twinkle.initCallbacks.push({ func: func, name: name }); }; Twinkle.defaultConfig = {}; /** * This holds the default set of preferences used by Twinkle. * It is important that all new preferences added here, especially admin-only ones, are also added to * |Twinkle.config.sections| in twinkleconfig.js, so they are configurable via the Twinkle preferences panel. * For help on the actual preferences, see the comments in twinkleconfig.js. */ Twinkle.defaultConfig = { // General userTalkPageMode: 'tab', dialogLargeFont: false, disabledModules: [], disabledSysopModules: [], // ARV spiWatchReport: 'yes', // Block defaultToBlock64: false, defaultToPartialBlocks: false, blankTalkpageOnIndefBlock: false, // Rollback autoMenuAfterRollback: false, openTalkPage: [ 'agf', 'norm', 'vand' ], openTalkPageOnAutoRevert: false, rollbackInPlace: false, markRevertedPagesAsMinor: [ 'vand' ], watchRevertedPages: [ 'agf', 'norm', 'vand', 'torev' ], watchRevertedExpiry: '1 month', offerReasonOnNormalRevert: true, confirmOnRollback: false, confirmOnMobileRollback: true, showRollbackLinks: [ 'diff', 'others' ], // DI (twinkleimage) notifyUserOnDeli: true, deliWatchPage: '1 month', deliWatchUser: '1 month', // Protect watchRequestedPages: 'yes', watchPPTaggedPages: 'default', watchProtectedPages: 'default', // PROD watchProdPages: '1 month', markProdPagesAsPatrolled: false, prodReasonDefault: '', logProdPages: false, prodLogPageName: 'BS günlüğü', // CSD speedySelectionStyle: 'buttonClick', watchSpeedyPages: [ 'g3', 'g5', 'g10', 'g11', 'g12' ], watchSpeedyExpiry: '1 month', markSpeedyPagesAsPatrolled: false, watchSpeedyUser: '1 month', // these next two should probably be identical by default welcomeUserOnSpeedyDeletionNotification: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], notifyUserOnSpeedyDeletionNomination: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], warnUserOnSpeedyDelete: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], promptForSpeedyDeletionSummary: [], deleteTalkPageOnDelete: true, deleteRedirectsOnDelete: true, deleteSysopDefaultToDelete: false, speedyWindowHeight: 500, speedyWindowWidth: 800, logSpeedyNominations: false, speedyLogPageName: 'HS günlüğü', noLogOnSpeedyNomination: [ 'g6' ], //Buradaki u1 -> g6 ve yukarıdaki db -> sil güncellemelerinden başka değişiklik yapılmadı. // Unlink unlinkNamespaces: [ '0', '10', '100', '118' ], // Warn defaultWarningGroup: '10', combinedSingletMenus: false, showSharedIPNotice: true, watchWarnings: '1 month', oldSelect: false, customWarningList: [], // XfD logXfdNominations: false, xfdLogPageName: 'SAS günlüğü', noLogOnXfdNomination: [], xfdWatchDiscussion: 'default', xfdWatchList: 'no', xfdWatchPage: '1 month', xfdWatchUser: '1 month', xfdWatchRelated: '1 month', markXfdPagesAsPatrolled: true, // Hidden preferences autolevelStaleDays: 3, // Huggle is 3, CBNG is 2 revertMaxRevisions: 50, // intentionally limited batchMax: 5000, batchChunks: 50, // Deprecated options, as a fallback for add-on scripts/modules summaryAd: ' ([[VP:TW|TW]])', deletionSummaryAd: ' ([[VP:TW|TW]])', protectionSummaryAd: ' ([[VP:TW|TW]])', // Tag groupByDefault: true, watchTaggedVenues: ['articles', 'drafts', 'redirects', 'files'], watchTaggedPages: '1 month', watchMergeDiscussions: '1 month', markTaggedPagesAsMinor: false, markTaggedPagesAsPatrolled: false, tagArticleSortOrder: 'cat', customTagList: [], customFileTagList: [], customRedirectTagList: [], // Welcome topWelcomes: false, watchWelcomes: '3 months', insertUsername: true, quickWelcomeMode: 'norm', quickWelcomeTemplate: 'welcome', customWelcomeList: [], customWelcomeSignature: true, // Talkback markTalkbackAsMinor: false, insertTalkbackSignature: true, // always sign talkback templates talkbackHeading: mw.config.get('wgUserName') + ' adlı kullanıcıdan yeni bir mesaj', mailHeading: "E-postanız var!", // Shared markSharedIPAsMinor: true }; Twinkle.getPref = function twinkleGetPref(name) { if (typeof Twinkle.prefs === 'object' && Twinkle.prefs[name] !== undefined) { return Twinkle.prefs[name]; } // Old preferences format, used before twinkleoptions.js was a thing if (typeof window.TwinkleConfig === 'object' && window.TwinkleConfig[name] !== undefined) { return window.TwinkleConfig[name]; } if (typeof window.FriendlyConfig === 'object' && window.FriendlyConfig[name] !== undefined) { return window.FriendlyConfig[name]; } // Backwards compatibility code because we renamed confirmOnFluff to confirmOnRollback, and confirmOnMobileFluff to confirmOnMobileRollback if (name === 'confirmOnRollback' && typeof Twinkle.prefs === 'object' && Twinkle.prefs.confirmOnFluff !== undefined) { return Twinkle.prefs.confirmOnFluff; } else if (name === 'confirmOnMobileRollback' && typeof Twinkle.prefs === 'object' && Twinkle.prefs.confirmOnMobileFluff !== undefined) { return Twinkle.prefs.confirmOnMobileFluff; } return Twinkle.defaultConfig[name]; }; /** * Adds a portlet menu to one of the navigation areas on the page. * * @return {string} portletId */ Twinkle.addPortlet = function() { /** @type {string} id of the target navigation area (skin dependent, on vector either of "#left-navigation", "#right-navigation", or "#mw-panel") */ let navigation; /** @type {string} id of the portlet menu to create, preferably start with "p-". */ let id; /** @type {string} name of the portlet menu to create. Visibility depends on the class used. */ let text; /** @type {Node} the id of the node before which the new item should be added, should be another item in the same list, or undefined to place it at the end. */ let nextnodeid; switch (mw.config.get('skin')) { case 'vector': case 'vector-2022': navigation = '#right-navigation'; id = 'p-twinkle'; text = 'TW'; // In order to get mw.util.addPortlet to generate a dropdown menu in vector and vector-2022, the nextnodeid must be p-cactions. Any other nextnodeid will generate a non-dropdown portlet instead. nextnodeid = 'p-cactions'; break; case 'timeless': navigation = '#page-tools .sidebar-inner'; id = 'p-twinkle'; text = 'Twinkle'; nextnodeid = 'p-userpagetools'; break; default: navigation = null; id = 'p-cactions'; } if (navigation === null) { return id; } // make sure navigation is a valid CSS selector const root = document.querySelector(navigation); if (!root) { return id; } // if we already created the portlet, return early. we don't want to create it again. const item = document.getElementById(id); if (item) { return id; } mw.util.addPortlet(id, text, '#' + nextnodeid); // The Twinkle dropdown menu has been added to the left of p-cactions, since that is the only spot that will create a dropdown menu. But we want it on the right. Move it to the right. if (mw.config.get('skin') === 'vector') { $('#p-twinkle').insertAfter('#p-cactions'); } else if (mw.config.get('skin') === 'vector-2022') { const $landmark = $('#right-navigation > .vector-page-tools-landmark'); $('#p-twinkle-dropdown').insertAfter($landmark); // .vector-page-tools-landmark is unstable and could change. If so, log it to console, to hopefully get someone's attention. if (!$landmark) { mw.log.warn('Unexpected change in DOM'); } } return id; }; /** * Builds a portlet menu if it doesn't exist yet, and adds a portlet link. This function runs at the top of every Twinkle module, ensuring that the first module to be loaded adds the portlet, and that every module can add a link to itself to the portlet. * * @param task Either a URL for the portlet link or a function to execute. */ Twinkle.addPortletLink = function(task, text, id, tooltip) { // Create a portlet to hold all the portlet links (if not created already). And get the portletId. const portletId = Twinkle.addPortlet(); // Create a portlet link and add it to the portlet. const link = mw.util.addPortletLink(portletId, typeof task === 'string' ? task : '#', text, id, tooltip); // Related to the hidden peer gadget that prevents jumpiness when the page first loads $('.client-js .skin-vector #p-cactions').css('margin-right', 'initial'); // Add a click listener for the portlet link if (typeof task === 'function') { $(link).on('click', (ev) => { task(); ev.preventDefault(); }); } // $.collapsibleTabs is a feature of Vector 2010 if ($.collapsibleTabs) { // Manually trigger a recalculation of what tabs to put where. This is to account for the space that the TW menu we just added is taking up. $.collapsibleTabs.handleResize(); } return link; }; /** * **************** General initialization code **************** */ const scriptpathbefore = mw.util.wikiScript('index') + '?title=', scriptpathafter = '&action=raw&ctype=text/javascript&happy=yes'; // Retrieve the user's Twinkle preferences $.ajax({ url: scriptpathbefore + 'Kullanıcı:' + encodeURIComponent(mw.config.get('wgUserName')) + '/twinkleoptions.js' + scriptpathafter, dataType: 'text' }) .fail(() => { console.log('Twinkle tercihleriniz yüklenemedi, varsayılan tercihlere başvuruluyor'); // eslint-disable-line no-console }) .done((optionsText) => { // Quick pass if user has no options if (optionsText === '') { return; } // Twinkle options are basically a JSON object with some comments. Strip those: optionsText = optionsText.replace(/(?:^(?:\/\/[^\n]*\n)*\n*|(?:\/\/[^\n]*(?:\n|$))*$)/g, ''); // First version of options had some boilerplate code to make it eval-able -- strip that too. This part may become obsolete down the line. if (optionsText.lastIndexOf('window.Twinkle.prefs = ', 0) === 0) { optionsText = optionsText.replace(/(?:^window.Twinkle.prefs = |;\n*$)/g, ''); } try { const options = JSON.parse(optionsText); if (options) { if (options.twinkle || options.friendly) { // Old preferences format Twinkle.prefs = $.extend(options.twinkle, options.friendly); } else { Twinkle.prefs = options; } // v2 established after unification of Twinkle/Friendly objects Twinkle.prefs.optionsVersion = Twinkle.prefs.optionsVersion || 1; } } catch (e) { mw.notify('Twinkle tercihleriniz ayrıştırılamadı', {type: 'error'}); } }) .always(() => { $(Twinkle.load); }); // Developers: you can import custom Twinkle modules here // For example, mw.loader.load(scriptpathbefore + "User:UncleDouggie/morebits-test.js" + scriptpathafter); Twinkle.load = function () { // Don't activate on special pages other than those listed here, so // that others load faster, especially the watchlist. let activeSpecialPageList = [ 'Block', 'Contributions', 'Recentchanges', 'Recentchangeslinked' ]; // wgRelevantUserName defined for non-sysops on Special:Block if (Morebits.userIsSysop) { activeSpecialPageList = activeSpecialPageList.concat([ 'DeletedContributions', 'Prefixindex' ]); } if (mw.config.get('wgNamespaceNumber') === -1 && activeSpecialPageList.indexOf(mw.config.get('wgCanonicalSpecialPageName')) === -1) { return; } // Prevent clickjacking if (window.top !== window.self) { return; } // Set custom Api-User-Agent header, for server-side logging purposes Morebits.wiki.Api.setApiUserAgent('Twinkle (' + mw.config.get('wgWikiID') + ')'); Twinkle.disabledModules = Twinkle.getPref('disabledModules').concat(Twinkle.getPref('disabledSysopModules')); // Redefine addInitCallback so that any modules being loaded now on are directly // initialised rather than added to initCallbacks array Twinkle.addInitCallback = function(func, name) { if (!name || Twinkle.disabledModules.indexOf(name) === -1) { func(); } }; // Initialise modules that were saved in initCallbacks array Twinkle.initCallbacks.forEach((module) => { Twinkle.addInitCallback(module.func, module.name); }); // Increases text size in Twinkle dialogs, if so configured if (Twinkle.getPref('dialogLargeFont')) { mw.util.addCSS('.morebits-dialog-content, .morebits-dialog-footerlinks { font-size: 100% !important; } ' + '.morebits-dialog input, .morebits-dialog select, .morebits-dialog-content button { font-size: inherit !important; }'); } // Hide the lingering space if the TW menu is empty const isVector = mw.config.get('skin') === 'vector' || mw.config.get('skin') === 'vector-2022'; if (isVector && Twinkle.getPref('portletType') === 'menu' && $('#p-twinkle').length === 0) { $('#p-cactions').css('margin-right', 'initial'); } // If using a skin with space for lots of modules, display a link to Twinkle Preferences const usingSkinWithDropDownMenu = mw.config.get('skin') === 'vector' || mw.config.get('skin') === 'vector-2022' || mw.config.get('skin') === 'timeless'; if (usingSkinWithDropDownMenu) { Twinkle.addPortletLink(mw.util.getUrl('Vikipedi:Twinkle/Tercihler'), 'Tercihler', 'tw-config', 'Twinkle tercihler sayfasını aç'); } }; /** * Twinkle-specific data shared by multiple modules * Likely customized per installation */ // Custom change tag(s) to be applied to all Twinkle actions, create at Special:Tags Twinkle.changeTags = 'twinkle'; // Available for actions that don't (yet) support tags // currently: FlaggedRevs and PageTriage Twinkle.summaryAd = ' ([[VP:TW|TW]])'; // Various hatnote templates, used when tagging (csd/xfd/tag/prod/protect) to // ensure MOS:ORDER Twinkle.hatnoteRegex = 'short description|kısa açıklama|hatnote|[İi]lknot|main|ana|correct title|doğru madde adı|dablink|distinguish|karıştırma|for|[İi]çin|further|daha fazla|selfref|year dab|similar names|highway detail hatnote|broader|about(?:-distinguish| other people)?|hakkında||other\\s?(?:hurricane(?: use)?s|people|persons|places|ships|uses(?: of)?)|redirect(?:-(?:distinguish|synonym|multi))?||yönlendirme|see\\s?(?:wiktionary|also(?: if exists)?)'; /* Twinkle-specific utility functions shared by multiple modules */ /** * When performing rollbacks with [rollback] links, then visiting a user talk page, some data such as page name can be prefilled into Wel/AIV/Warn. Twinkle calls this a "prefill". This method gets a prefill, either from URL parameters (e.g. &vanarticle=Test) or from data previously stored using Twinkle.setPrefill() */ Twinkle.getPrefill = function (key) { Twinkle.prefill = Twinkle.prefill || {}; if (!Object.prototype.hasOwnProperty.call(Twinkle.prefill, key)) { Twinkle.prefill[key] = mw.util.getParamValue(key); } return Twinkle.prefill[key]; }; /** * When performing rollbacks with [rollback] links, then visiting a user talk page, some data such as page name can be prefilled into Wel/AIV/Warn. Twinkle calls this a "prefill". This method sets a prefill. This data will be lost if the page is refreshed, unless it is added to the URL as a parameter. */ Twinkle.setPrefill = function (key, value) { Twinkle.prefill = Twinkle.prefill || {}; Twinkle.prefill[key] = value; }; /* * Used in XFD and PROD */ Twinkle.makeFindSourcesDiv = function makeSourcesDiv(divID) { if (!$(divID).length) { return; } if (!Twinkle.findSources) { const parser = new Morebits.wiki.Preview($(divID)[0]); parser.beginRender('({{Kaynak ara|' + Morebits.pageNameNorm + '}})', 'VP:SAS').then(() => { // Save for second-time around Twinkle.findSources = parser.previewbox.innerHTML; $(divID).removeClass('morebits-previewbox'); }); } else { $(divID).html(Twinkle.findSources); } }; /** * Used in batch, unlink, and deprod to sort pages by namespace, as * json formatversion=2 sorts by pageid instead (#1251) */ Twinkle.sortByNamespace = function(first, second) { return first.ns - second.ns || (first.title > second.title ? 1 : -1); }; /** * Used in batch listings to link to the page in question with > */ Twinkle.generateArrowLinks = function (checkbox) { const link = Morebits.htmlNode('a', ' >'); link.setAttribute('class', 'tw-arrowpage-link'); link.setAttribute('href', mw.util.getUrl(checkbox.value)); link.setAttribute('target', '_blank'); checkbox.nextElementSibling.append(link); }; /** * Used in deprod and unlink listings to link the page title */ Twinkle.generateBatchPageLinks = function (checkbox) { const $checkbox = $(checkbox); const link = Morebits.htmlNode('a', $checkbox.val()); link.setAttribute('class', 'tw-batchpage-link'); link.setAttribute('href', mw.util.getUrl($checkbox.val())); link.setAttribute('target', '_blank'); $checkbox.next().prepend([link, ' ']); }; }()); // </nowiki> /* twinkle sonu */ /* JWB başlangıcı */ mw.loader.load( '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript' ); // Backlink: [[en:User:Joeytje50/JWB.js/load.js]] /* JWB sonu */ pt08sx3ubkth3mckmyocn9n30b0vexy 240644 240643 2026-10-16T18:46:08Z Brightt11 34669 240644 javascript text/javascript /* who is active başlangıcı */ $( function () { const filteredLinks = []; const localizedUserNamespace = mw.config.get( 'wgFormattedNamespaces' )[2]; $( '.mw-parser-output' ). find( 'a[title^="User:"], a[title^="' + localizedUserNamespace + ':"]' ). each( function() { const link = $( this ); const href = decodeURI( link.attr( 'href' ) ); const userRegex = new RegExp( '((User)|(' + localizedUserNamespace + ')):(.*?)(?=&|$)' ); const username = href.match(userRegex); const index = username[0].indexOf( '/' ); if ( username[0].indexOf( '/' ) === -1 ) { filteredLinks.push( { username: username[0], element: link } ); } } ); if ( !filteredLinks.length ) { return; } const RECENT = 'recent'; const THISYEAR = 'thisyear'; const OVERAYEAR = 'overayear'; const messages = { en: { recent: 'Edited recently', thisyear: 'Edited this year', overayear: 'Edited over a year ago' }, tr: { recent: 'Aktif', thisyear: 'Yarı aktif', overayear: 'Aktif değil' }, de: { recent: 'kürzlich bearbeitet', thisyear: 'in diesem Jahr bearbeitet', overayear: 'vor über einem Jahr bearbeitet' } }; const localizedMessages = function () { const lang = mw.config.get( 'wgUserLanguage' ); if ( lang in messages ) { return messages[lang]; } return messages.en; }(); const getLastActiveMarker = function ( timestamp ) { const date = Date.parse( timestamp ); const now = Date.now(); const diff = Math.floor( ( now - date ) / ( 1000 * 60 * 60 * 24 ) ); var timespan = RECENT; if ( diff > 365 ) { timespan = OVERAYEAR; } else if ( diff > 15 ) { timespan = THISYEAR; } const iconPath = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/resources/lib/ooui/themes/wikimediaui/images/icons/userContributions-ltr.svg'; const marker = "<span class='mw-whoisactivegadget-span mw-whoisactivegadget-" + timespan + "'>" + "<img src='" + iconPath + "' class='mw-whoisactivegadget-filter-" + timespan + "'/> " + localizedMessages[timespan] + "<span>"; return $( marker ); }; mw.loader.using( [ 'mediawiki.api' ], function () { filteredLinks.forEach( function( item ) { const username = item.username; const element = item.element; const api = new mw.Api(); api.get( { format: 'json', action: 'query', list: 'usercontribs', uclimit: '1', ucuser: username } ).then( function ( result ) { if ( result.query.usercontribs.length ) { const timestamp = result.query.usercontribs[0].timestamp; getLastActiveMarker( timestamp ).insertAfter( element ); } } ); } ); } ); } ); /*who is active sonu*/ /* twinkle başlangıcı /* /** * +-------------------------------------------------------------------------+ * | === WARNING: GLOBAL GADGET FILE === | * | Changes to this page affect many users. | * | Please discuss changes at [[WT:TW]] before editing. | * +-------------------------------------------------------------------------+ * * Imported from github [https://github.com/wikimedia-gadgets/twinkle]. * All changes should be made in the repository, otherwise they will be lost. * * ---------- * * This is AzaToth's Twinkle, the popular script sidekick for newbies, admins, and * every Wikipedian in between. Visit [[WP:TW]] for more information. */ // <nowiki> /* global Morebits */ (function() { // Check if account is experienced enough to use Twinkle if (!Morebits.userIsInGroup('autoconfirmed') && !Morebits.userIsInGroup('confirmed')) { return; } const Twinkle = {}; window.Twinkle = Twinkle; // allow global access Twinkle.initCallbacks = []; /** * Adds a callback to execute when Twinkle has loaded. * * @param {Function} func * @param {string} [name] - name of module used to check if is disabled. * If name is not given, module is loaded unconditionally. */ Twinkle.addInitCallback = function twinkleAddInitCallback(func, name) { Twinkle.initCallbacks.push({ func: func, name: name }); }; Twinkle.defaultConfig = {}; /** * This holds the default set of preferences used by Twinkle. * It is important that all new preferences added here, especially admin-only ones, are also added to * |Twinkle.config.sections| in twinkleconfig.js, so they are configurable via the Twinkle preferences panel. * For help on the actual preferences, see the comments in twinkleconfig.js. */ Twinkle.defaultConfig = { // General userTalkPageMode: 'tab', dialogLargeFont: false, disabledModules: [], disabledSysopModules: [], // ARV spiWatchReport: 'yes', // Block defaultToBlock64: false, defaultToPartialBlocks: false, blankTalkpageOnIndefBlock: false, // Rollback autoMenuAfterRollback: false, openTalkPage: [ 'agf', 'norm', 'vand' ], openTalkPageOnAutoRevert: false, rollbackInPlace: false, markRevertedPagesAsMinor: [ 'vand' ], watchRevertedPages: [ 'agf', 'norm', 'vand', 'torev' ], watchRevertedExpiry: '1 month', offerReasonOnNormalRevert: true, confirmOnRollback: false, confirmOnMobileRollback: true, showRollbackLinks: [ 'diff', 'others' ], // DI (twinkleimage) notifyUserOnDeli: true, deliWatchPage: '1 month', deliWatchUser: '1 month', // Protect watchRequestedPages: 'yes', watchPPTaggedPages: 'default', watchProtectedPages: 'default', // PROD watchProdPages: '1 month', markProdPagesAsPatrolled: false, prodReasonDefault: '', logProdPages: false, prodLogPageName: 'BS günlüğü', // CSD speedySelectionStyle: 'buttonClick', watchSpeedyPages: [ 'g3', 'g5', 'g10', 'g11', 'g12' ], watchSpeedyExpiry: '1 month', markSpeedyPagesAsPatrolled: false, watchSpeedyUser: '1 month', // these next two should probably be identical by default welcomeUserOnSpeedyDeletionNotification: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], notifyUserOnSpeedyDeletionNomination: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], warnUserOnSpeedyDelete: [ 'db', 'g1', 'g2', 'g3', 'g4', 'g6', 'g10', 'g11', 'g12', 'g13', 'g14', 'a1', 'a2', 'a3', 'a7', 'a9', 'a10', 'a11', 'f1', 'f2', 'f3', 'f7', 'f9', 'r3', 'u5' ], promptForSpeedyDeletionSummary: [], deleteTalkPageOnDelete: true, deleteRedirectsOnDelete: true, deleteSysopDefaultToDelete: false, speedyWindowHeight: 500, speedyWindowWidth: 800, logSpeedyNominations: false, speedyLogPageName: 'HS günlüğü', noLogOnSpeedyNomination: [ 'g6' ], //Buradaki u1 -> g6 ve yukarıdaki db -> sil güncellemelerinden başka değişiklik yapılmadı. // Unlink unlinkNamespaces: [ '0', '10', '100', '118' ], // Warn defaultWarningGroup: '10', combinedSingletMenus: false, showSharedIPNotice: true, watchWarnings: '1 month', oldSelect: false, customWarningList: [], // XfD logXfdNominations: false, xfdLogPageName: 'SAS günlüğü', noLogOnXfdNomination: [], xfdWatchDiscussion: 'default', xfdWatchList: 'no', xfdWatchPage: '1 month', xfdWatchUser: '1 month', xfdWatchRelated: '1 month', markXfdPagesAsPatrolled: true, // Hidden preferences autolevelStaleDays: 3, // Huggle is 3, CBNG is 2 revertMaxRevisions: 50, // intentionally limited batchMax: 5000, batchChunks: 50, // Deprecated options, as a fallback for add-on scripts/modules summaryAd: ' ([[VP:TW|TW]])', deletionSummaryAd: ' ([[VP:TW|TW]])', protectionSummaryAd: ' ([[VP:TW|TW]])', // Tag groupByDefault: true, watchTaggedVenues: ['articles', 'drafts', 'redirects', 'files'], watchTaggedPages: '1 month', watchMergeDiscussions: '1 month', markTaggedPagesAsMinor: false, markTaggedPagesAsPatrolled: false, tagArticleSortOrder: 'cat', customTagList: [], customFileTagList: [], customRedirectTagList: [], // Welcome topWelcomes: false, watchWelcomes: '3 months', insertUsername: true, quickWelcomeMode: 'norm', quickWelcomeTemplate: 'welcome', customWelcomeList: [], customWelcomeSignature: true, // Talkback markTalkbackAsMinor: false, insertTalkbackSignature: true, // always sign talkback templates talkbackHeading: mw.config.get('wgUserName') + ' adlı kullanıcıdan yeni bir mesaj', mailHeading: "E-postanız var!", // Shared markSharedIPAsMinor: true }; Twinkle.getPref = function twinkleGetPref(name) { if (typeof Twinkle.prefs === 'object' && Twinkle.prefs[name] !== undefined) { return Twinkle.prefs[name]; } // Old preferences format, used before twinkleoptions.js was a thing if (typeof window.TwinkleConfig === 'object' && window.TwinkleConfig[name] !== undefined) { return window.TwinkleConfig[name]; } if (typeof window.FriendlyConfig === 'object' && window.FriendlyConfig[name] !== undefined) { return window.FriendlyConfig[name]; } // Backwards compatibility code because we renamed confirmOnFluff to confirmOnRollback, and confirmOnMobileFluff to confirmOnMobileRollback if (name === 'confirmOnRollback' && typeof Twinkle.prefs === 'object' && Twinkle.prefs.confirmOnFluff !== undefined) { return Twinkle.prefs.confirmOnFluff; } else if (name === 'confirmOnMobileRollback' && typeof Twinkle.prefs === 'object' && Twinkle.prefs.confirmOnMobileFluff !== undefined) { return Twinkle.prefs.confirmOnMobileFluff; } return Twinkle.defaultConfig[name]; }; /** * Adds a portlet menu to one of the navigation areas on the page. * * @return {string} portletId */ Twinkle.addPortlet = function() { /** @type {string} id of the target navigation area (skin dependent, on vector either of "#left-navigation", "#right-navigation", or "#mw-panel") */ let navigation; /** @type {string} id of the portlet menu to create, preferably start with "p-". */ let id; /** @type {string} name of the portlet menu to create. Visibility depends on the class used. */ let text; /** @type {Node} the id of the node before which the new item should be added, should be another item in the same list, or undefined to place it at the end. */ let nextnodeid; switch (mw.config.get('skin')) { case 'vector': case 'vector-2022': navigation = '#right-navigation'; id = 'p-twinkle'; text = 'TW'; // In order to get mw.util.addPortlet to generate a dropdown menu in vector and vector-2022, the nextnodeid must be p-cactions. Any other nextnodeid will generate a non-dropdown portlet instead. nextnodeid = 'p-cactions'; break; case 'timeless': navigation = '#page-tools .sidebar-inner'; id = 'p-twinkle'; text = 'Twinkle'; nextnodeid = 'p-userpagetools'; break; default: navigation = null; id = 'p-cactions'; } if (navigation === null) { return id; } // make sure navigation is a valid CSS selector const root = document.querySelector(navigation); if (!root) { return id; } // if we already created the portlet, return early. we don't want to create it again. const item = document.getElementById(id); if (item) { return id; } mw.util.addPortlet(id, text, '#' + nextnodeid); // The Twinkle dropdown menu has been added to the left of p-cactions, since that is the only spot that will create a dropdown menu. But we want it on the right. Move it to the right. if (mw.config.get('skin') === 'vector') { $('#p-twinkle').insertAfter('#p-cactions'); } else if (mw.config.get('skin') === 'vector-2022') { const $landmark = $('#right-navigation > .vector-page-tools-landmark'); $('#p-twinkle-dropdown').insertAfter($landmark); // .vector-page-tools-landmark is unstable and could change. If so, log it to console, to hopefully get someone's attention. if (!$landmark) { mw.log.warn('Unexpected change in DOM'); } } return id; }; /** * Builds a portlet menu if it doesn't exist yet, and adds a portlet link. This function runs at the top of every Twinkle module, ensuring that the first module to be loaded adds the portlet, and that every module can add a link to itself to the portlet. * * @param task Either a URL for the portlet link or a function to execute. */ Twinkle.addPortletLink = function(task, text, id, tooltip) { // Create a portlet to hold all the portlet links (if not created already). And get the portletId. const portletId = Twinkle.addPortlet(); // Create a portlet link and add it to the portlet. const link = mw.util.addPortletLink(portletId, typeof task === 'string' ? task : '#', text, id, tooltip); // Related to the hidden peer gadget that prevents jumpiness when the page first loads $('.client-js .skin-vector #p-cactions').css('margin-right', 'initial'); // Add a click listener for the portlet link if (typeof task === 'function') { $(link).on('click', (ev) => { task(); ev.preventDefault(); }); } // $.collapsibleTabs is a feature of Vector 2010 if ($.collapsibleTabs) { // Manually trigger a recalculation of what tabs to put where. This is to account for the space that the TW menu we just added is taking up. $.collapsibleTabs.handleResize(); } return link; }; /** * **************** General initialization code **************** */ const scriptpathbefore = mw.util.wikiScript('index') + '?title=', scriptpathafter = '&action=raw&ctype=text/javascript&happy=yes'; // Retrieve the user's Twinkle preferences $.ajax({ url: scriptpathbefore + 'Kullanıcı:' + encodeURIComponent(mw.config.get('wgUserName')) + '/twinkleoptions.js' + scriptpathafter, dataType: 'text' }) .fail(() => { console.log('Twinkle tercihleriniz yüklenemedi, varsayılan tercihlere başvuruluyor'); // eslint-disable-line no-console }) .done((optionsText) => { // Quick pass if user has no options if (optionsText === '') { return; } // Twinkle options are basically a JSON object with some comments. Strip those: optionsText = optionsText.replace(/(?:^(?:\/\/[^\n]*\n)*\n*|(?:\/\/[^\n]*(?:\n|$))*$)/g, ''); // First version of options had some boilerplate code to make it eval-able -- strip that too. This part may become obsolete down the line. if (optionsText.lastIndexOf('window.Twinkle.prefs = ', 0) === 0) { optionsText = optionsText.replace(/(?:^window.Twinkle.prefs = |;\n*$)/g, ''); } try { const options = JSON.parse(optionsText); if (options) { if (options.twinkle || options.friendly) { // Old preferences format Twinkle.prefs = $.extend(options.twinkle, options.friendly); } else { Twinkle.prefs = options; } // v2 established after unification of Twinkle/Friendly objects Twinkle.prefs.optionsVersion = Twinkle.prefs.optionsVersion || 1; } } catch (e) { mw.notify('Twinkle tercihleriniz ayrıştırılamadı', {type: 'error'}); } }) .always(() => { $(Twinkle.load); }); // Developers: you can import custom Twinkle modules here // For example, mw.loader.load(scriptpathbefore + "User:UncleDouggie/morebits-test.js" + scriptpathafter); Twinkle.load = function () { // Don't activate on special pages other than those listed here, so // that others load faster, especially the watchlist. let activeSpecialPageList = [ 'Block', 'Contributions', 'Recentchanges', 'Recentchangeslinked' ]; // wgRelevantUserName defined for non-sysops on Special:Block if (Morebits.userIsSysop) { activeSpecialPageList = activeSpecialPageList.concat([ 'DeletedContributions', 'Prefixindex' ]); } if (mw.config.get('wgNamespaceNumber') === -1 && activeSpecialPageList.indexOf(mw.config.get('wgCanonicalSpecialPageName')) === -1) { return; } // Prevent clickjacking if (window.top !== window.self) { return; } // Set custom Api-User-Agent header, for server-side logging purposes Morebits.wiki.Api.setApiUserAgent('Twinkle (' + mw.config.get('wgWikiID') + ')'); Twinkle.disabledModules = Twinkle.getPref('disabledModules').concat(Twinkle.getPref('disabledSysopModules')); // Redefine addInitCallback so that any modules being loaded now on are directly // initialised rather than added to initCallbacks array Twinkle.addInitCallback = function(func, name) { if (!name || Twinkle.disabledModules.indexOf(name) === -1) { func(); } }; // Initialise modules that were saved in initCallbacks array Twinkle.initCallbacks.forEach((module) => { Twinkle.addInitCallback(module.func, module.name); }); // Increases text size in Twinkle dialogs, if so configured if (Twinkle.getPref('dialogLargeFont')) { mw.util.addCSS('.morebits-dialog-content, .morebits-dialog-footerlinks { font-size: 100% !important; } ' + '.morebits-dialog input, .morebits-dialog select, .morebits-dialog-content button { font-size: inherit !important; }'); } // Hide the lingering space if the TW menu is empty const isVector = mw.config.get('skin') === 'vector' || mw.config.get('skin') === 'vector-2022'; if (isVector && Twinkle.getPref('portletType') === 'menu' && $('#p-twinkle').length === 0) { $('#p-cactions').css('margin-right', 'initial'); } // If using a skin with space for lots of modules, display a link to Twinkle Preferences const usingSkinWithDropDownMenu = mw.config.get('skin') === 'vector' || mw.config.get('skin') === 'vector-2022' || mw.config.get('skin') === 'timeless'; if (usingSkinWithDropDownMenu) { Twinkle.addPortletLink(mw.util.getUrl('Vikipedi:Twinkle/Tercihler'), 'Tercihler', 'tw-config', 'Twinkle tercihler sayfasını aç'); } }; /** * Twinkle-specific data shared by multiple modules * Likely customized per installation */ // Custom change tag(s) to be applied to all Twinkle actions, create at Special:Tags Twinkle.changeTags = 'twinkle'; // Available for actions that don't (yet) support tags // currently: FlaggedRevs and PageTriage Twinkle.summaryAd = ' ([[VP:TW|TW]])'; // Various hatnote templates, used when tagging (csd/xfd/tag/prod/protect) to // ensure MOS:ORDER Twinkle.hatnoteRegex = 'short description|kısa açıklama|hatnote|[İi]lknot|main|ana|correct title|doğru madde adı|dablink|distinguish|karıştırma|for|[İi]çin|further|daha fazla|selfref|year dab|similar names|highway detail hatnote|broader|about(?:-distinguish| other people)?|hakkında||other\\s?(?:hurricane(?: use)?s|people|persons|places|ships|uses(?: of)?)|redirect(?:-(?:distinguish|synonym|multi))?||yönlendirme|see\\s?(?:wiktionary|also(?: if exists)?)'; /* Twinkle-specific utility functions shared by multiple modules */ /** * When performing rollbacks with [rollback] links, then visiting a user talk page, some data such as page name can be prefilled into Wel/AIV/Warn. Twinkle calls this a "prefill". This method gets a prefill, either from URL parameters (e.g. &vanarticle=Test) or from data previously stored using Twinkle.setPrefill() */ Twinkle.getPrefill = function (key) { Twinkle.prefill = Twinkle.prefill || {}; if (!Object.prototype.hasOwnProperty.call(Twinkle.prefill, key)) { Twinkle.prefill[key] = mw.util.getParamValue(key); } return Twinkle.prefill[key]; }; /** * When performing rollbacks with [rollback] links, then visiting a user talk page, some data such as page name can be prefilled into Wel/AIV/Warn. Twinkle calls this a "prefill". This method sets a prefill. This data will be lost if the page is refreshed, unless it is added to the URL as a parameter. */ Twinkle.setPrefill = function (key, value) { Twinkle.prefill = Twinkle.prefill || {}; Twinkle.prefill[key] = value; }; /* * Used in XFD and PROD */ Twinkle.makeFindSourcesDiv = function makeSourcesDiv(divID) { if (!$(divID).length) { return; } if (!Twinkle.findSources) { const parser = new Morebits.wiki.Preview($(divID)[0]); parser.beginRender('({{Kaynak ara|' + Morebits.pageNameNorm + '}})', 'VP:SAS').then(() => { // Save for second-time around Twinkle.findSources = parser.previewbox.innerHTML; $(divID).removeClass('morebits-previewbox'); }); } else { $(divID).html(Twinkle.findSources); } }; /** * Used in batch, unlink, and deprod to sort pages by namespace, as * json formatversion=2 sorts by pageid instead (#1251) */ Twinkle.sortByNamespace = function(first, second) { return first.ns - second.ns || (first.title > second.title ? 1 : -1); }; /** * Used in batch listings to link to the page in question with > */ Twinkle.generateArrowLinks = function (checkbox) { const link = Morebits.htmlNode('a', ' >'); link.setAttribute('class', 'tw-arrowpage-link'); link.setAttribute('href', mw.util.getUrl(checkbox.value)); link.setAttribute('target', '_blank'); checkbox.nextElementSibling.append(link); }; /** * Used in deprod and unlink listings to link the page title */ Twinkle.generateBatchPageLinks = function (checkbox) { const $checkbox = $(checkbox); const link = Morebits.htmlNode('a', $checkbox.val()); link.setAttribute('class', 'tw-batchpage-link'); link.setAttribute('href', mw.util.getUrl($checkbox.val())); link.setAttribute('target', '_blank'); $checkbox.next().prepend([link, ' ']); }; }()); // </nowiki> /* twinkle sonu */ /* JWB başlangıcı */ mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript'); /* JWB sonu */ 8rflrpacnufa7o07c89wto2ap10ap01 Şablon:AWB uyarı 2 10 47571 240633 2026-10-16T16:18:03Z Brightt11 34669 "{{ambox | tür = content | resim = [[File:OOjs UI icon alert-warning.svg|36px]] | sorun = '''AutoWikiBrowser uygulamasında sorun yaşıyorsanız web tabanlı JWB Script'i deneyebilirsiniz.'''}} <noinclude> {{Belgeleme}} </noinclude>" içeriğiyle yeni sayfa oluşturdu 240633 wikitext text/x-wiki {{ambox | tür = content | resim = [[File:OOjs UI icon alert-warning.svg|36px]] | sorun = '''AutoWikiBrowser uygulamasında sorun yaşıyorsanız web tabanlı JWB Script'i deneyebilirsiniz.'''}} <noinclude> {{Belgeleme}} </noinclude> 4nlqq2ikxmpqxmw62jcuiuz64x8px61 240642 240633 2026-10-16T18:24:11Z Brightt11 34669 + 240642 wikitext text/x-wiki {{ambox | tür = content | resim = [[File:OOjs UI icon alert-warning.svg|36px]] | sorun = '''AutoWikiBrowser uygulamasında sorun yaşıyorsanız web tabanlı <span class="plainlinks">[{{fullurl:Vikisöz:AutoWikiBrowser/Script}} '''JWB Script'i'''] deneyebilirsiniz.'''}} <noinclude> {{Belgeleme}} </noinclude> kh1nqmn92opk0xdc6vop5kt3so80590 Vikisöz:AutoWikiBrowser/Script 4 47572 240635 2026-10-16T16:20:12Z Brightt11 34669 fork from enwiki. 240635 wikitext text/x-wiki {{esnek yönlendirme|w:en:User:Joeytje50/JWB}} laiuq7ewqbn01ip23vzevt5q7ioyfdn 240638 240635 2026-10-16T18:17:32Z Brightt11 34669 240638 wikitext text/x-wiki {{esnek yönlendirme|User:Brightt11/JWB}} 9quxwrlnm7c1okgdhqt1q70jf336x5p 240639 240638 2026-10-16T18:17:43Z Brightt11 34669 240639 wikitext text/x-wiki {{esnek yönlendirme|User:Brightt11/JWB.js}} mg5hexrfco4d2rl6s9esem6d3ov908i Kullanıcı:Brightt11/JWB.js 2 47573 240636 2026-10-16T18:14:39Z Brightt11 34669 fork from enwiki. en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js 240636 javascript text/javascript /* JWB başlangıcı */ /** <nowiki> * Install this script by pasting the following in your personal JavaScript file: mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript'); * Or for users on en.wikipedia.org: {{subst:lusc|User:Joeytje50/JWB.js/load.js}} * Note that this script will only run on the 'Project:AutoWikiBrowser/Script' page. * This script is based on the downloadable AutoWikiBrowser. * * @licence * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html * @version 4.5.2 * @author Joeytje50 * </nowiki> */ window.JWBdeadman = false; // ADMINS: in case of fire, set this variable to true to disable this entire tool for all users //TODO: more advanced pagelist-generating options //TODO: generate page list based on images on a page //TODO: Add feature to perform general cleanup (<table> to {|, fullurl-links to wikilinks, removing underscores from wikilinks) //TODO: Add report button to AJAX error alert box //TODO: Re-add errored pages to the page list //TODO: Automatically generate full list of protection levels //TODO: Add 'Ignore quotes' alongside 'Ignore unparsed content'; for example: Ignore [] Unparsed content [] Quotes //TODO: Read Wikipedia:AutoWikiBrowser/Config for when not to apply typo fixes //TODO: RETF disable any \b and some other cases //TODO: Fix deletedrevs deprecated API //TODO: Handle response 429 (Too Many Requests) by rate-limiting Pre-parse mode //Cleanup / modernize: // .indexOf('') != -1 -> .includes() // mw for requests, instead of ajax // Optional?.chaining?.properties /***** Global object/variables *****/ window.JWB = {}; //The main global object for the script. (function() { // Easier way to change import location for local debugging etc. JWB.imports = { 'JWB.css': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.css&action=raw&ctype=text/css', 'i18n.js': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/i18n.js&action=raw&ctype=text/javascript', 'i18n': {}, 'RETF.js': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/RETF.js&action=raw&ctype=text/javascript', 'worker.js':'//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/worker.js&action=raw&ctype=text/javascript', }; JWB.allLoaded = false; let objs = ['page', 'api', 'worker', 'fn', 'pl', 'messages', 'setup', 'settings', 'ns']; for (let i=0;i<objs.length;i++) { JWB[objs[i]] = {}; } JWB.summarySuffix = ' (via JWB)'; if (document.location.hostname == 'en.wikipedia.org') JWB.summarySuffix = ' (via [[WP:JWB]])'; JWB.lang = mw.config.get('wgUserLanguage').replace('-', '_'); JWB.contentLang = mw.config.get('wgContentLanguage').replace('-', '_'); JWB.index_php = mw.config.get('wgScript'); JWB.isStopped = true; JWB.tooltip = window.tooltipAccessKeyPrefix || ''; let configext = 'js'; if (document.location.hostname.split('.').slice(-2).join('.') == 'wikia.com' || document.location.hostname.split('.').slice(-2).join('.') == 'fandom.com') { //LEGACY: fallback to settings on css for Wikia; uses JSON now. configext = 'css'; } JWB.settingspage = 'JWB-settings.'+configext; if (window.hasOwnProperty('JWBSETTINGS')) { JWB.settingspage = JWBSETTINGS+'-settings.'+configext; delete window.JWBSETTINGS; //clean up the global variable } JWB.hasJSON = false; // whether or not the wiki supports JSON userpages (mw 1.31+). JWB.hasSMW = false; // whether or not the wiki has SMW installed. })(); /***** User verification *****/ (function() { if (mw.config.get('wgCanonicalNamespace')+':'+mw.config.get('wgTitle') !== 'Project:AutoWikiBrowser/Script' || JWB.allowed === false || mw.config.get('wgUserName') === null) { JWB.allowed = false; return; } mw.loader.load(JWB.imports['JWB.css'], 'text/css'); mw.loader.load('mediawiki.diff.styles'); JWB.langs = []; $.getScript(JWB.imports['i18n.js'], function() { if (JWB.allowed === false) { JWB.checkInit(); // deny access without attempting to load other languages. return; } if (JWB.lang !== 'en' && JWB.imports.i18n.hasOwnProperty(JWB.lang)) { JWB.langs.push(JWB.imports.i18n[JWB.lang]); JWB.messages[JWB.lang] = JWB.messages[JWB.lang] || null; } else if (JWB.lang !== 'en' && JWB.lang !== 'qqx') { // this only happens if the language file does not exist. JWB.lang = 'en'; } if (JWB.contentLang !== 'en' && JWB.contentLang !== JWB.lang && JWB.imports.i18n.hasOwnProperty(JWB.contentLang)) { JWB.langs.push(JWB.imports.i18n[JWB.contentLang]); JWB.messages[JWB.contentLang] = JWB.messages[JWB.contentLang] || null; } if (JWB.langs.length) { $.when.apply($, JWB.langs.map(url => $.getScript(url))).done(function(r) { JWB.checkInit(); }); } else { // no more languages to load. console.log('no languages needed loading'); JWB.checkInit(); } }); //RegEx Typo Fixing $.getScript(JWB.imports['RETF.js'], function() { $('#refreshRETF').click(RETF.load); }); if (window.JWBdeadman === true) { window.JWB = false; // disable all access alert("This tool has been temporarily been disabled by Wikipedia admins due to issues it would otherwise cause. Please check back soon to see if it is working again."); return false; } else if (!window.Worker) { // https://caniuse.com/webworkers - this should not happen for any sensible human being. Either you're on IE<10, or you're just testing my patience. alert("Web Workers are not supported in this browser. Please use a more modern browser to use JWB. Most matching and replacing features are not supported in this browser."); } (new mw.Api()).get({ action: 'query', titles: 'Project:AutoWikiBrowser/CheckPageJSON|MediaWiki:Tag-JWB', prop: 'info|revisions', meta: 'userinfo|siteinfo', rvprop: 'content', uiprop: 'groups', siprop: 'namespaces|usergroups|extensions', indexpageids: true, format: 'json', }).done(function(response) { if (response.error) { alert('API error: ' + response.error.info); JWB = false; //preventing further access. No verification => no access. return; } JWB.ns = response.query.namespaces; //saving for later // This will execute before JWB.init() and therefore before JWB.setup.load() loading the user's settings. let wikigroups = response.query.usergroups; for (var u of wikigroups) { if (u.rights.indexOf('edituserjson') !== -1) { JWB.hasJSON = true; break; } } // Check if we've got SMW on this wiki let extensions = response.query.extensions; for (var e of extensions) { if (e.name == "SemanticMediaWiki") { JWB.hasSMW = true; break; } } JWB.username = response.query.userinfo.name; //preventing any "hacks" that change wgUserName or mw.config.wgUserName var groups = response.query.userinfo.groups; var page = Object.values(response.query.pages).find(page => page.title.includes("AutoWikiBrowser/CheckPageJSON")); var tagPage = Object.values(response.query.pages).find(page => page.title.includes("Tag-JWB")); JWB.hasTag = (tagPage.missing === undefined); var users = []; var bots = []; JWB.sysop = groups.indexOf('sysop') !== -1; if (response.query.pageids[0] !== '-1') { var checkPageData = JSON.parse(page.revisions[0]['*']); users = checkPageData.enabledusers; if ("enabledbots" in checkPageData) { bots = checkPageData.enabledbots; } } else { users = false; //fallback when page doesn't exist if (JWB.sysop) { // Check and inform admins if their checkpage is the unsupported format. (new mw.Api()).get({ action: 'query', titles: 'Project:AutoWikiBrowser/CheckPage', prop: 'info', indexpageids: true, }).done(function(oldpage){ var q = oldpage.query; if (q.pageids[0] != '-1' && !q.pages[q.pageids[0]].hasOwnProperty('redirect')) { // CheckPageJSON does not exist, and CheckPage does exist, and is not a redirect. // This indicates the checkpage needs to be ported to JSON. Notify admins. prompt('Warning: The AWB checkpage found at Project:AutoWikiBrowser/CheckPage is no longer supported.\n'+ 'Please convert this checkpage to a JSON checkpage. See the URL below for more information.\n'+ 'After creating the JSON checkpage, you can use "Special:ChangeContentModel" to change the content model to JSON.', 'https://en.wikipedia.org/wiki/Wikipedia:AutoWikiBrowser/CheckPage_format'); } }); } } JWB.bot = groups.indexOf('bot') !== -1 && (users === false || bots.includes(JWB.username)); // Temporary global debugging variables JWB.debug = [groups.indexOf('bot'), users === false, bots && bots.indexOf(JWB.username)]; if (JWB.username === "Joeytje50" && response.query.userinfo.id === 13299994) {//TEMP: Dev full access to entire interface. JWB.bot = true; users.push("Joeytje50"); } if (JWB.sysop || response.query.pageids[0] === '-1' || users === false || users.includes(JWB.username) || bots.includes(JWB.username)) { JWB.allowed = true; JWB.checkInit(); //init if everything necessary has been loaded } else { if (JWB.allLoaded) { //run this after messages have loaded, so the message that shows is in the user's language alert(JWB.msg('not-on-list')); } JWB = false; //prevent further access } }).fail(function(xhr, error) { alert(JWB.msg('verify-error') + '\n' + error); JWB = false; //preventing further access. No verification => no access. }); })(); /***** API functions *****/ //Main template for API calls JWB.api.call = function(data, callback, onerror) { data.format = 'json'; if (data.action !== 'query' && data.action !== 'compare' && data.action !== 'ask' && data.action !== 'parse' && data.action !== 'watch') { data.bot = true; // mark edits as bot if (JWB.hasTag) data.tags = 'JWB'; // tag with 'JWB' } $.ajax({ data: data, dataType: 'json', url: mw.config.get('wgScriptPath') + '/api.php', type: 'POST', success: function(response) { if (response.error) { if (onerror && onerror(response, 'API') === false) return; alert('API error: ' + response.error.info); JWB.stop(); } else { callback(response); } }, // onerror: if it exists and returns false, do not show error alert. Otherwise, do show alert. error: function(xhr, error) { if (onerror && onerror(error, 'AJAX') === false) return; alert('AJAX error: ' + error); JWB.stop(); } }); }; //Get page diff, and process it for more interactivity JWB.api.diff = function(callback) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('diff'); var editBoxInput = $('#editBoxArea').val(); var redirect = $('input.redirects:checked').val(); var data = { action: 'compare', indexpageids: true, fromtitle: JWB.page.name, //toslots: 'main', // TODO: Once this gets supported more widely, convert to the non-deprecated toslots system. //'totext-main': editBoxInput, totext: editBoxInput, topst: true, }; if (redirect=='follow') data.redirects = true; JWB.api.call(data, function(response) { var diff; diff = response.compare['*']; if (diff === '') { diff = '<h2>'+JWB.msg('no-changes-made')+'</h2>'; } else { diff = '<table class="diff">'+ '<colgroup>'+ '<col class="diff-marker">'+ '<col class="diff-content">'+ '<col class="diff-marker">'+ '<col class="diff-content">'+ '</colgroup>'+ '<tbody>'+diff+'</tbody></table>'; } $('#resultWindow').html(diff); $('.diff-lineno').each(function() { var lineNumMatch = $(this).html().match(/\d+/); if (lineNumMatch) { $(this).parent().attr('data-line',parseInt(lineNumMatch[0])-1).addClass('lineheader'); } }); $('table.diff tr').each(function() { //add data-line attribute to every line, relative to the previous one. Used for click event. if (!$(this).next().is('[data-line]') && !$(this).next().children('td.diff-deletedline + td.diff-empty').length) { $(this).next().attr('data-line',parseInt($(this).data('line'))+1); } else if ($(this).next().children('td.diff-deletedline + td.diff-empty').length) { $(this).next().attr('data-line',$(this).data('line')); //copy over current data-line for deleted lines to prevent them from messing up counting. } }); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } }, function(err, type) { if (type == 'API' && err.error.code == 'missingtitle') { // missingtitle is to be expected when editing a page that doesn't exist; just show a message and move on. $('#resultWindow').html('<span style="font-weight:bold;color:red;">'+JWB.msg('page-not-exists')+'</span>'); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } return false; // stop propagation of error; do not show alerts. } }); }; //Retrieve page contents/info, process them, and store information in JWB.page object. JWB.api.get = function(pagename) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.pageCount(); if (!JWB.list[0] || JWB.isStopped) { return JWB.stop(); } if (pagename === '#PRE-PARSE-STOP') { var curval = $('#articleList').val(); $('#articleList').val(curval.substr(curval.indexOf('\n') + 1)); $('#preparse').prop('checked', false); JWB.stop(); return; } let cgns = JWB.ns[14]['*']; let skipcg = $('#skipCategories').val(); // prepend Category: before all categories and turn CSV(,) into CSV(|). skipcg = skipcg.replace(new RegExp('(^|,|\\|)('+cgns+':)?', 'gi'), '|'+cgns+':').substr(1); var redirect = $('input.redirects:checked').val(); var data = { action: 'query', prop: 'info|revisions|categories', inprop: 'watched|protection', type: 'csrf|watch', titles: pagename, rvprop: 'content|timestamp|ids', rvlimit: '1', cllimit: 'max', clcategories: skipcg, indexpageids: true, meta: 'userinfo|tokens', uiprop: 'hasmsg' }; if (redirect=='follow'||redirect=='skip') data.redirects = true; if (JWB.sysop) { data.list = 'deletedrevs'; } JWB.status('load-page'); JWB.api.call(data, function(response) { if (response.query.userinfo.hasOwnProperty('messages')) { var view = mw.config.get('wgScriptPath') + '?title=Special:MyTalk'; var viewNew = view + '&diff=cur'; JWB.status( '<span style="color:red;font-weight:bold;">'+ JWB.msg('status-newmsg', '<a href="'+view+'" target="_blank">'+JWB.msg('status-talklink')+'</a>', '<a href="'+viewNew+'" target="_blank">'+JWB.msg('status-difflink')+'</a>')+ '</span>', true); alert(JWB.msg('new-message')); JWB.stop(); return; } JWB.page = response.query.pages[response.query.pageids[0]]; JWB.page.token = response.query.tokens.csrftoken; JWB.page.watchtoken = response.query.tokens.watchtoken; JWB.page.name = JWB.list[0].split('|')[0]; var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0; JWB.page.pagevar = JWB.list[0].substr(varOffset); JWB.page.content = JWB.page.revisions ? JWB.page.revisions[0]['*'] : ''; JWB.page.exists = !response.query.pages["-1"]; JWB.page.deletedrevs = response.query.deletedrevs; JWB.page.watched = JWB.page.hasOwnProperty('watched'); JWB.page.protections = JWB.page.restrictiontypes; if (response.query.redirects) { JWB.page.name = response.query.redirects[0].to; } JWB.page.path = mw.config.get('wgArticlePath').replace('$1', encodeURIComponent(JWB.page.name)); // check for skips that can be determined before replacing if (!JWB.fn.allowBots(JWB.page.content, JWB.username) || !JWB.fn.allowBots(JWB.page.content)) { // skip if {{bots}} template forbids editing on this page by user OR by JWB in general JWB.log('nobots', JWB.page.name); return JWB.next(); } else if (JWB.page.categories !== undefined || // skip because of a matching category as passed via clcategories. ($('#exists-no').prop('checked') && !JWB.page.exists) || ($('#exists-yes').prop('checked') && JWB.page.exists) || (redirect==='skip' && response.query.redirects) // variable redirect is defined outside this callback function. ) { // simple skip rules JWB.log('skip', JWB.page.name); return JWB.next(); } // Check skip contains rules. var containRegex = $('#containRegex').prop('checked'), containFlags = $('#containFlags').val(); var skipContains, skipNotContains; if (containRegex) { JWB.status('check-skips'); var skipping = false; // for tracking if match is found in synchronous calls. if ($('#skipContains').val().length) { JWB.worker.match(JWB.page.content, $('#skipContains').val(), containFlags, function(result, err) { console.log('Contains', result, err); if (result !== null && err === undefined) { JWB.log('skip', JWB.page.name); JWB.next(); // next() also cancels the skipNotContains. skipping = true; return; } // else continue with the queued worker job that checks skipNotContains }); } if (skipping) { console.log('skipped page before replaces'); return; } if ($('#skipNotContains').val().length) { JWB.worker.match(JWB.page.content, $('#skipNotContains').val(), containFlags, function(result, err) { console.log('Not contains', result, err); if (result === null && err === undefined) { JWB.log('skip', JWB.page.name); JWB.next(); // also cancels the replace skipping = true; return; } // else move on to replacing }); } if (skipping) { console.log('skipped page before replaces'); return; } } else { skipContains = $('#skipContains').val(); skipNotContains = $('#skipNotContains').val(); if ((skipContains && JWB.page.content.includes(skipContains)) || (skipNotContains && !JWB.page.content.includes(skipNotContains))) { console.log('skipped page before replaces'); return JWB.next(); } JWB.status('done', true); } JWB.replace(JWB.page.content, function(newContent) { if (JWB.isStopped === true) return; if ($('#skipNoChange').prop('checked') && JWB.page.content === newContent) { //skip if no changes are made JWB.log('skip', JWB.page.name); return JWB.next(); } else { JWB.editPage(newContent); } JWB.updateButtons(); }); }); }; //Some functions with self-explanatory names: JWB.api.submit = function(page) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('submit'); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; if ((typeof page === 'string' && page !== JWB.page.name) || $('#currentpage a').html().replace(/&amp;/g, '&') !== JWB.page.name) { console.log(page, JWB.page.name, $('#currentpage a').html()); JWB.stop(); alert(JWB.msg('autosave-error', JWB.msg('tab-log'))); $('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' ')); return; } var newval = $('#editBoxArea').val(); var diffsize = newval.length - JWB.page.content.length; if ($('#sizelimit').val() != 0 && Math.abs(diffsize) > parseInt($('#sizelimit').val())){ alert(JWB.msg('size-limit-exceeded', diffsize > 0 ? '+'+diffsize : diffsize)); JWB.status('done', true); return; } var data = { title: JWB.page.name, summary: summary, action: 'edit', basetimestamp: JWB.page.revisions ? JWB.page.revisions[0].timestamp : '', token: JWB.page.token, text: newval, watchlist: $('#watchPage').val() }; if ($('#minorEdit').prop('checked')) data.minor = true; JWB.api.call(data, function(response) { JWB.log('edit', response.edit.title, response.edit.newrevid); }, function(error, errtype) { var cont = false; if (errtype == 'API') { cont = confirm("API error: " + error.error.info + "\n" + JWB.msg('confirm-continue')); } else { cont = confirm("AJAX error: " + error + "\n" + JWB.msg('confirm-continue')); } if (!cont) { JWB.stop(); } return false; // do not fall back on default error handling }); // While the edit is submitting, continue to the next page to edit. JWB.status('done', true); JWB.next(); }; JWB.api.preview = function(callback) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('preview'); JWB.api.call({ title: JWB.page.name, action: 'parse', pst: true, text: $('#editBoxArea').val(), prop: 'text|categorieshtml|modules|jsconfigvars', useskin: mw.config.get('skin') }, function(response) { $('#resultWindow').html(response.parse.text['*']); $('#resultWindow div.previewnote').remove(); $('#resultWindow').append(response.parse.categorieshtml['*']); for (var entry of Object.entries(response.parse.jsconfigvars)) { mw.config.set(entry[0], entry[1]); } mw.loader.using(response.parse.modules.concat(response.parse.modulescripts, response.parse.modulestyles), function() { mw.hook('wikipage.content').fire($('#resultWindow .mw-parser-output')); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } }); }); }; JWB.api.move = function() { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('move'); var topage = $('#moveTo').val().replace(/\$x/gi, JWB.page.pagevar); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var data = { action: 'move', from: JWB.page.name, to: topage, token: JWB.page.token, reason: summary, ignorewarnings: 'yes' }; if ($('#moveTalk').prop('checked')) data.movetalk = true; if ($('#moveSubpage').prop('checked')) data.movesubpages = true; if ($('#suppressRedir').prop('checked')) data.noredirect = true; JWB.api.call(data, function(response) { JWB.log('move', response.move.from, response.move.to); JWB.status('done', true); if (!$('#moveTo').val().match(/\$x/i)) $('#moveTo').val('')[0].focus(); //clear entered move-to pagename if it's not based on the pagevar JWB.next(topage); }); }; JWB.api.del = function() { if (JWB.isStopped) return; // prevent new API calls when stopped var del_action = (!JWB.page.exists ? 'un' : '') + 'delete'; JWB.status(del_action); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var data = { action: del_action, title: JWB.page.name, token: JWB.page.token, reason: summary }; if ($('#deleteTalk').prop('checked')) data[del_action + 'talk'] = true; JWB.api.call(data, function(response) { JWB.log(del_action, (response['delete']||response.undelete).title); JWB.status('done', true); JWB.next(response.undelete && response.undelete.title); }); }; JWB.api.protect = function() { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('protect'); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var editprot = $('#editProt').val(); var moveprot = $('#moveProt').val() || editprot; var uploadprot = $('#uploadProt').val() || editprot; var protstring = 'edit='+editprot+'|move='+moveprot; if (!JWB.page.exists) protstring = 'create='+editprot; if (JWB.page.protections.includes('upload')) protstring += '|upload='+uploadprot; JWB.api.call({ action: 'protect', title: JWB.page.name, token: JWB.page.token, reason: summary, expiry: $('#protectExpiry').val()!==''?$('#protectExpiry').val():'infinite', protections: protstring, }, function(response) { var protactions = ''; var prots = response.protect.protections; for (var i=0;i<prots.length;i++) { if (typeof prots[i].edit == 'string') { protactions += ' edit: '+(prots[i].edit || 'all'); } else if (typeof prots[i].move == 'string') { protactions += ' move: '+(prots[i].move || 'all'); } else if (typeof prots[i].create == 'string') { protactions += ' create: '+(prots[i].create || 'all'); } else if (typeof prots[i].upload == 'string') { protactions += ' upload: '+(prots[i].upload || 'all'); } } protactions += ' expires: '+prots[0].expiry; JWB.log('protect', response.protect.title, protactions); JWB.status('done', false); JWB.next(response.protect.title); }); }; JWB.api.watch = function() { JWB.status('watch'); var data = { action: 'watch', title: JWB.page.name, token: JWB.page.watchtoken }; if (JWB.page.watched) data.unwatch = true; JWB.api.call(data, function(response) { JWB.status('<span style="color:green;">'+ JWB.msg('status-watch-'+(JWB.page.watched ? 'removed' : 'added'), "'"+JWB.page.name+"'")+ '</span>', true); JWB.page.watched = !JWB.page.watched; $('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) ); }); }; /***** Pagelist functions *****/ JWB.pl.iterations = 0; JWB.pl.done = true; JWB.pl.stop = function() { if (JWB.pl.done) { JWB.pl.iterations = 0; $('#pagelistPopup [disabled]:not(fieldset [disabled]), #pagelistPopup legend input, #pagelistPopup button').prop('disabled', false); $('#pagelistPopup legend input').trigger('change'); $('#pagelistPopup button img').remove(); } }; JWB.pl.getNSpaces = function() { var list = $('#pagelistPopup [name="namespace"]')[0]; return $('#pagelistPopup [name="namespace"]').val().join('|'); //.val() returns an array of selected options. }; JWB.pl.getList = function(abbrs, lists, data) { $('#pagelistPopup button, #pagelistPopup input, #pagelistPopup select, #pagelistPopup button').prop('disabled', true); JWB.pl.iterations++; if (data.ask !== undefined) { JWB.pl.SMW(data.ask); // execute SMW call in parallel JWB.pl.done = false; data.ask = undefined; } if (!abbrs.length) { JWB.pl.done = true; return; // don't execute the rest; only a SMW query was entered. } data.action = 'query'; var nspaces = JWB.pl.getNSpaces(); for (let i=0;i<abbrs.length;i++) { if (nspaces) data[abbrs[i]+'namespace'] = data[abbrs[i]+'namespace'] || nspaces; // if namespaces are already set, use that instead (for apnamespace) data[abbrs[i]+'limit'] = 'max'; } let linksList = lists.indexOf('links'); if (linksList !== -1) { data.prop = 'links'; lists.splice(linksList, 1); } data.list = lists.join('|'); console.log('generating:', data); JWB.api.call(data, function(response) { var maxiterate = 100; //allow up to 100 consecutive requests at a time to avoid overloading the server. if (!response.query) response.query = {}; if (response.watchlistraw) response.query.watchlistraw = response.watchlistraw; //adding some consistency var plist = []; if (response.query.pages) { var links; for (var id in response.query.pages) { links = response.query.pages[id].links; for (let i=0;i<links.length;i++) { plist.push(links[i].title); } } } for (var l in response.query) { if (l === 'pages') continue; for (let i=0;i<response.query[l].length;i++) { plist.push(response.query[l][i].title); } } //add the result to the pagelist immediately, as opposed to saving it all up and adding in 1 go like AWB does $('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n')); JWB.pageCount(); var cont = response.continue; console.log("Continue",JWB.pl.iterations, cont); if (cont && JWB.pl.iterations <= maxiterate) { var lists = []; if (response.query) { //compatibility with the code I wrote for the old query-continue. TODO: make this unnecessary? for (var list in response.query) { lists.push(list); //add to the new array of &list= values } } var abbrs = []; for (var abbr in cont) { data[abbr] = cont[abbr]; //add the &xxcontinue= value to the data if (abbr != 'continue') { abbrs.push(abbr.replace('continue','')); //find out what xx is and add it to the list of abbrs } } JWB.pl.getList(abbrs, lists, data); //recursive function to get every page of a list } else { if (JWB.pl.iterations > maxiterate) { JWB.status('pl-over-lim', true); } else { JWB.status('done', true); } JWB.pl.stop(); // if JWB.pl.done == true show stopped interface. Otherwise mark as done. JWB.pl.done = true; } }, function() { //on error, simply reset and let the user work with what he has JWB.status('done', true); JWB.pl.stop(); JWB.pl.done = true; }); }; JWB.pl.SMW = function(query) { var data = { action: 'ask', query: query }; JWB.api.call(data, function(response) { console.log(response); let list = response.query.results; let pagevar = response.query.printrequests[1]; let pagevar_type = pagevar && pagevar.typeid; if (pagevar) { // either pagevar === undefined, or it's the first printrequest. pagevar = pagevar.label; } let plist = []; for (let l in list) { let page = list[l]; let name = page.fulltext; let suff; if (pagevar) try { let val = page.printouts[pagevar][0]; if (!val) continue; // this page does not contain this property. switch (pagevar_type) { case '_boo': suff = val == 't'; // true if 't' else false; break; case '_wpg': suff = val.fulltext; break; case '_dat': // val.raw is also available but the unconventional format makes it a lot less convenient. suff = val.timestamp; break; case '_qty': suff = val.value + ' ' + val.unit; break; case '_mlt_rec': // I doubt this is used anywhere, but it's not too hard to support. suff = val.Text.item[0]; break; case '_ref_rec': // not supported; references contain too many properties. break; default: suff = val; } } catch(e) { console.error(e); // show error but ignore. Something is wrong in SMW query/api. } if (suff) { plist.push(name + '|' + suff); } else { plist.push(name); } } $('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n')); JWB.pageCount(); JWB.pl.stop(); // if JWB.pl.done == true show stopped interface. Otherwise mark as done. JWB.pl.done = true; }); }; //JWB.pl.getList(['wr'], ['watchlistraw'], {}) for watchlists JWB.pl.generate = function() { var $fields = $('#pagelistPopup fieldset').not('[disabled]'); $('#pagelistPopup').find('button[type="submit"]').append('<img src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="15" height="15" alt="'+JWB.msg('status-alt')+'"/>'); var abbrs = [], lists = [], data = {'continue': ''}; $fields.each(function() { var list = $(this).find('legend input').attr('name'); var abbr; if (list === 'linksto') { //Special case since this fieldset features 3 merged lists in 1 fieldset if (!$('[name="title"]').val()) return; $('[name="backlinks"], [name="embeddedin"], [name="imageusage"]').filter(':checked').each(function() { var val = this.value; abbrs.push(val); lists.push(this.name); data[val+'title'] = $('[name="title"]').val(); data[val+'filterredir'] = $('[name="filterredir"]:checked').val(); if ($('[name="redirect"]').prop('checked')) data[val+'redirect'] = true; }); } else if (list === 'smwask') { data.ask = $(this).find('#smwquery').val(); } else { //default input system if ($(this).find('#psstrict').prop('checked')) { // different list if prefixsearch is strict let $input = $(this).find('#psstrict'); list = $input.attr('name'); abbr = $input.val(); } else { abbr = $(this).find('legend input').val(); } lists.push(list); abbrs.push(abbr); $(this).find('input').not('legend input').each(function() { if ((this.type === 'checkbox' || this.type === 'radio') && this.checked === false) return; if (this.id == 'psstrict') return; // ignore psstrict; it only affects how pssearch is handled var name, val; if (this.id == 'cmtitle') { // making sure the page has a Category: prefix, in case the user left it out let cgns = JWB.ns[14]['*']; // name for Category: namespace if (!this.value.startsWith(cgns+':')) { this.value = cgns+':'+this.value; } } if (this.id == 'pssearch' && this.name == 'apprefix') { // apprefix needs namespace separate from pagename name = this.name; let split = this.value.split(':'); val = split[1] || split[0]; let nsid = 0; if (split[1]) { // if a namespace is given for (let ns in JWB.ns) { if (JWB.ns[ns]['*'] == split[0]) { nsid = JWB.ns[ns].id; break; } } } data.apnamespace = nsid; } else { name = this.name; val = this.value; } if (data.hasOwnProperty(name)) { data[name] += '|'+val; } else { data[name] = val; } }); console.log(abbrs, lists, data); } }); if (abbrs.length || data.ask) JWB.pl.getList(abbrs, lists, data); else JWB.pl.stop(); }; /***** Setup functions *****/ JWB.setup.save = function(name) { name = name || prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-store')), $('#loadSettings').val()); if (name === null) return; var self = JWB.settings[name] = { string: {}, bool: {}, replaces: [] }; //inputs with a text value $('textarea, input[type="text"], input[type="number"], select').not('.replaces input, #editBoxArea, #settings *').each(function() { if (typeof $(this).val() == 'string') { self.string[this.id] = this.value.replace(/\n{2,}/g,'\n'); } else { self.string[this.id] = $(this).val(); } }); self.replaces = []; $('.replaces').each(function() { if ($(this).find('.replaceText').val() || $(this).find('.replaceWith').val()) { self.replaces.push({ replaceText: $(this).find('.replaceText').val(), replaceWith: $(this).find('.replaceWith').val(), useRegex: $(this).find('.useRegex').prop('checked'), regexFlags: $(this).find('.regexFlags').val(), ignoreNowiki: $(this).find('.ignoreNowiki').prop('checked') }); } }); $('input[type="radio"], input[type="checkbox"]').not('.replaces input').each(function() { self.bool[this.id] = this.checked; }); if (!$('#loadSettings option[value="'+name+'"]').length) { $('#loadSettings').append('<option value="'+name+'">'+name+'</option>'); } $('#loadSettings').val(name); console.log(self); }; JWB.setup.apply = function(name) { name = name && JWB.settings[name] ? name : 'default'; var self = JWB.settings[name]; $('#loadSettings').val(name); $('.replaces + .replaces').remove(); //reset find&replace inputs $('.replaces input[type="text"]').val(''); $('.useRegex').each(function() {this.checked = false;}); $('#pagelistPopup legend input').trigger('change'); //fix checked state of pagelist generating inputs for (var a in self.string) { $('#'+a).val(self.string[a]); } for (var b in self.bool) { $('#'+b).prop('checked', self.bool[b]); } var cur; for (var c=0;c<self.replaces.length;c++) { if ($('.replaces').length <= c) $('.moreReplaces[data-insert="before"')[0].click(); cur = self.replaces[c]; for (var d in cur) { if (cur[d] === true || cur[d] === false) { $('.replaces').eq(c).find('.'+d).prop('checked', cur[d]); } else { $('.replaces').eq(c).find('.'+d).val(cur[d]); } } } JWB.listReplaces(); $('.useRegex, #containRegex,'+ '#pagelistPopup legend input,'+ '#viaJWB, #enableRETF').trigger('change'); //reset disabled inputs }; JWB.setup.getObj = function() { var settings = []; for (var i in JWB.settings) { if (i != '_blank') { settings.push('"' + i + '": ' + JSON.stringify(JWB.settings[i])); } } return '{\n\t' + settings.join(',\n\t').split('{{subst:').join('{{#JWB-SAFESUBST:#') + '\n}'; }; JWB.setup.submit = function() { var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val()); if (name === null) return; if ($.trim(name) === '') name = 'default'; JWB.setup.save(name); JWB.status('setup-submit'); JWB.api.call({ action: 'query', meta: 'tokens', }, function(response) { let edittoken = response.query.tokens.csrftoken; JWB.api.call({ title: 'User:'+JWB.username+'/'+JWB.settingspage, summary: JWB.msg(['setup-summary', JWB.contentLang]), action: 'edit', token: edittoken, text: JWB.setup.getObj(), minor: true }, function(response) { JWB.status('done', true); JWB.log('edit', response.edit.title, response.edit.newrevid); }); }); }; //TODO: use blob uri JWB.setup.download = function() { var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val()); if (name === null) return; if ($.trim(name) === '') name = 'default'; JWB.setup.save(name); JWB.status('setup-dload'); var url = 'data:application/json;base64,' + btoa(unescape(encodeURIComponent(JWB.setup.getObj()))); var elem = $('#download-anchor')[0]; if (HTMLAnchorElement.prototype.hasOwnProperty('download')) { //use download attribute when possible, for its ability to specify a filename elem.href = url; elem.click(); setTimeout(function() {elem.removeAttribute('href');}, 2000); } else { //fallback to iframes for browsers with no support for download="" attributes elem = $('#download-iframe')[0]; elem.src = url.replace('application/json', 'application/octet-stream'); setTimeout(function() {elem.removeAttribute('src');}, 2000); } JWB.status('done', true); }; JWB.setup.import = function(e) { e.preventDefault(); file = (e.dataTransfer||this).files[0]; if ($(this).is('#import')) { //reset input this.outerHTML = this.outerHTML; $('#import').change(JWB.setup.import); } if (!window.hasOwnProperty('FileReader')) { alert(JWB.msg('old-browser')); JWB.status('old-browser', '<a target="_blank" href="'+JWB.index_php+'?title=Special:MyPage/'+JWB.settingspage+'">/'+JWB.settingspage+'</a>'); return; } if (file.name.split('.').pop().toLowerCase() !== 'json') { alert(JWB.msg('not-json')); return; } JWB.status('Processing file'); var reader = new FileReader(); reader.readAsText(file); reader.onload = function(e) { JWB.status('done', true); try { //Exclusion regex based on http://stackoverflow.com/a/23589204/1256925 //Removes all JS comments from the file, except when they're between quotes. var c = reader.result; var data = JSON.parse(c.replace(/("[^"]*")|(\/\*[\w\W]*\*\/|\/\/[^\n]*)/g, function(match, g1, g2) { if (g1) return g1; })); JWB.setup.extend(data); } catch(e) { alert(JWB.msg('json-err', e.message, JWB.msg('json-err-upload'))); console.log(e); //also log the error for further info return; } }; JWB.status('Processing file'); }; JWB.setup.load = function() { JWB.status('setup-load'); var user = JWB.username||mw.config.get('wgUserName'); var oldtitle = "User:" + user + '/'+JWB.settingspage; // page title for what was used before version 4.0 var newtitle = "User:" + user + '/JWB-settings.json'; // new page title for all settings pages. var titles = oldtitle; // if the old title isn't JWB-settings.json, also query the new title. if (oldtitle !== newtitle && JWB.hasJSON) { titles += '|' + newtitle; } JWB.api.call({ action: 'query', titles: titles, prop: 'info|revisions', meta: 'tokens', rvprop: 'content', indexpageids: true }, function(response) { if (JWB === false) return; //user is not allowed to use JWB var firstrun = !JWB.setup.initialised; JWB.setup.initialised = true; var edittoken = response.query.tokens.csrftoken; // determine correct page to get settings from var pages = response.query.pages, ids = response.query.pageids; var page, exists = true; if (ids.length == 2) { var page0 = pages[ids[0]], page1 = pages[ids[1]]; var oldpage, newpage; if (page0.title == oldtitle) { oldpage = page0; newpage = page1; } else { oldpage = page1; newpage = page0; } if (oldpage.missing === undefined && oldpage.redirect === undefined) { // old page exists and is not a redirect if (newpage.missing === undefined) { // both old AND new page exist; throw error and load neither page. let jsredir = "https://www.mediawiki.org/wiki/Help:Redirects#JavaScript_page_redirect"; prompt(JWB.msg('duplicate-settings', oldtitle, newtitle, jsredir), jsredir); exists = false; } else { // old page exists but new page doesn't; move the page to the new location. JWB.setup.moveNew(oldtitle, newtitle, edittoken); JWB.settingspage = 'JWB-settings.json'; return; } } else { // Old page either doesn't exist or is a redirect. Don't bother with it. page = newpage; exists = (page.missing === undefined); JWB.settingspage = 'JWB-settings.json'; } } else { page = pages[ids[0]]; exists = (page.missing === undefined); } if (!exists) { // settings page does not exist; don't load anything if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded. return; } var data = page.revisions[0]['*'].split('{{#JWB-SAFESUBST:#').join('{{subst:'); if (!data) { // settings page is empty; don't load anything. if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded. return; } try { data = JSON.parse(data); } catch(e) { alert(JWB.msg('json-err', e.message, JWB.msg('json-err-page', JWB.settingspage)) || 'JSON error:\n'+e.message); JWB.setup.save('default'); return; } JWB.setup.extend(data); JWB.status('done', true); }); }; JWB.setup.moveNew = function(from, to, token) { var data = { action: 'move', from: from, to: to, token: token, reason: JWB.msg(['setup-move-summary', JWB.contentLang]), noredirect: true, // if possible, suppress redirects; the old page will no longer be needed if the new page exists. movesubpages: true, // if any movetalk: true, // if any ignorewarnings: true, }; if (JWB.hasTag) data.tags = 'JWB'; (new mw.Api()).post(data).done(function(response) { if (response.error === undefined) { JWB.log('move', from, to); JWB.settingspage = to.split('/')[1]; alert(JWB.msg('moved-settings', from, to, JWB.msg('tab-log'))); JWB.setup.load(); // load settings from newly moved page. } }); }; JWB.setup.extend = function(obj) { $.extend(JWB.settings, obj); if (!JWB.settings.hasOwnProperty('default')) { JWB.setup.save('default'); } for (var i in JWB.settings) { if ($('#loadSettings').find('option[value="'+i+'"]').length) continue; $('#loadSettings').append('<option value="'+i+'">'+i+'</option>'); } JWB.setup.apply($('#loadSettings').val()); }; JWB.setup.del = function() { var name = $('#loadSettings').val(); if (name === '_blank') return alert(JWB.msg('setup-delete-blank')); var temp = {}; temp[name] = JWB.settings[name]; JWB.setup.temp = $.extend({}, temp); delete JWB.settings[name]; $('#loadSettings').val('default'); if (name === 'default') { JWB.setup.apply('_blank'); JWB.setup.save('default'); JWB.status(['del-default', '<a href="javascript:JWB.setup.undelete();">'+JWB.msg('status-del-undo')+'</a>'], true); } else { $('#loadSettings').find('[value="'+name+'"]').remove(); JWB.setup.apply(); JWB.status(['del-setup', name, '<a href="javascript:JWB.setup.undelete();">'+JWB.msg('status-del-undo')+'</a>'], true); } }; JWB.setup.undelete = function() { JWB.setup.extend(JWB.setup.temp); JWB.status('done', true); }; /***** Main other functions *****/ //Show status message status-`action`, or status-`action[0]` with arguments `action[1:]` JWB.status = function(action, done) { if (JWB.bot && $('#autosave').prop('checked') && !JWB.isStopped) { $('#summary, .editbutton, #movePage, #deletePage, #protectPage, #skipPage').prop('disabled', true); //Disable summary when auto-saving } else { $('#summary, .editbutton, #movePage, #deletePage, #protectPage, #skipPage').prop('disabled', !done); //Disable box when not done (so busy loading). re-enable when done loading. } var status; if (action instanceof Array) { action[0] = 'status-'+action[0]; status = JWB.msg.apply(this, action); } else { status = JWB.msg('status-'+action); } if (status === false) return; if (status) { if (!done) { //spinner if not done status += ' <img src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="15" height="15" alt="'+JWB.msg('status-alt')+'"/>'; } } else { status = action; } $('#status').html(status); JWB.pageCount(); return action=='done'; }; JWB.pageCount = function() { if (JWB.allowed === false||!$('#articleList').length) return; $('#articleList').val(($('#articleList').val()||'').replace(/(^[ \t]*$\n)*/gm, '')); JWB.list = $('#articleList').val().split('\n'); var count = JWB.list.length; if (count === 1 && JWB.list[0] === '') count = 0; $('#totPages').html(count); }; //Generate list of replaces to be performed JWB.listReplaces = function() { JWB.replaces = []; $('.replaces').each(function() { var $this = $(this); var r = []; r[0] = $this.find('.replaceText').val() .replace(/\$x/gi, JWB.page.pagevar) // fill in pagevar .replace(/\\{2}/g, '\\').replace(/\\n/g,'\n'); // handle \n -> newline; r[1] = $this.find('.replaceWith').val(); if (r[0].length == 0 && r[1].length == 0) return; // don't bother replacing 2 empty strings. r[2] = $this.find('.regexFlags').val(); r[3] = $this; JWB.replaces.push(r); }); if (JWB.replaces.length > 1 || ( JWB.replaces.length == 1 && $('.JWBtabc .replaceText').val() == '' && $('.JWBtabc .replaceWith').val() == '' )) { // There are replace rules in the replaces popup $('#replacesButton').addClass('replacesActive'); } else { $('#replacesButton').removeClass('replacesActive'); } }; //Perform all specified find&replace actions JWB.replace = function(input, callback) { JWB.status('replacing'); if (!JWB.worker.isWorking() && JWB.worker.supported) { // if the worker is not already working, then re-init to make sure we've not got any broken leftovers from the previous page JWB.worker.init(); } JWB.newContent = input; JWB.pageCount(); var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0; JWB.page.pagevar = JWB.list[0].substr(varOffset); $.each(JWB.replaces, function(i, r) { var replaceText = r[0], replaceWith = r[1], regexFlags = r[2]; var $this = r[3]; var useRegex = replaceText.length == 0 || $this.find('.useRegex').prop('checked'); var replace = replaceText || '$'; // empty string => append (replace /$/ with text) if (useRegex && regexFlags.indexOf('_') !== -1) { replace = replace.replace(/[ _]/g, '[ _]'); //replaces any of [Space OR underscore] with a match for spaces or underscores. replace = replace.replace(/(\[[^\]]*)\[ _\]/g, '$1 _'); //in case a [ _] was placed inside another [] match, remove the []. regexFlags = regexFlags.replace('_', ''); } //apply replaces where \n and \\ work in both regular text and regex mode. var rWith = replaceWith.replace(/\$x/gi, JWB.page.pagevar).replace(/\\{2}/g, '\\').replace(/\\n/g,'\n'); if (rWith.length === 0 && replace === '$') return; try { let replaceDone = function(result, err) { console.log('done replacing', result, err); if (err === undefined) { JWB.newContent = result; if (JWB.worker.queue.length == 0 && JWB.worker.supported) { // all workers are done JWB.status('done', true); callback(JWB.newContent); } } else if (err == 'Timeout exceeded') { if (JWB.worker.queue.length == 0 && JWB.worker.supported) { // all workers have exceeded their time and/or have finished JWB.status('done', true); callback(JWB.newContent); // newContent remains unmodified due to timeout. } } }; if ($this.find('.ignoreNowiki').prop('checked')) { if (!useRegex) { replace = replace.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); regexFlags = 'g'; } JWB.worker.unparsedReplace("~"+"~~JWB.newContent", replace, regexFlags, rWith, replaceDone); } else if (useRegex) { JWB.worker.replace("~"+"~~JWB.newContent", replace, regexFlags, rWith, replaceDone); } else { JWB.newContent = JWB.newContent.split(replace).join(rWith); //global replacement without having to escape all special chars. } } catch(e) { console.log('Regex error:', e); JWB.stop(); return JWB.status('regex-err', false); } }); if ($('#enableRETF').prop('checked')) { JWB.newContent = RETF.replace(JWB.newContent); } if (!JWB.worker.isWorking()) { // no workers were called JWB.status('done', true); callback(JWB.newContent); } }; JWB.skipRETF = function() { if (!$('#enableRETF').prop('checked')) return; // RETF is not enabled to begin with if (JWB.isStopped === true) return; // don't mess with the edit box when stopped $('#enableRETF').prop('checked', false); JWB.replace(JWB.page.content, function(newContent) { JWB.editPage(newContent); JWB.updateButtons(); $('#enableRETF').prop('checked', true); }); }; // Edit the current page and pre-fill the newContent. JWB.editPage = function(newContent) { $('#editBoxArea').val(newContent); $('#currentpage').html(JWB.msg('editbox-currentpage', JWB.page.name, JWB.page.path)); if ($('#preparse').prop('checked')) { $('#articleList').val($.trim($('#articleList').val()) + '\n' + JWB.list[0]); //move current page to the bottom JWB.next(); return; } var onLoadFunctions = { diff: JWB.api.diff, preview: JWB.api.preview }; var autoSaveCallback = JWB.bot && $('#autosave').prop('checked') ? function() { //timeout will take #throttle's value * 1000, if it's a number above 0. Currently defaults to 0. setTimeout(JWB.api.submit, Math.max(+$('#throttle').val() || 0, 0) * 1000, JWB.page.name); } : null; var onLoadFunction = onLoadFunctions[$('#onLoad').val()] || onLoadFunctions.diff; onLoadFunction(autoSaveCallback); }; //Adds a line to the logs tab. JWB.log = function(action, page, info) { var d = new Date(); var pagee = encodeURIComponent(page); var extraInfo = '', actionStat = ''; switch (action) { case 'edit': if (typeof info === 'undefined') { action = 'null-edit'; actionStat = 'nullEdits'; } else { extraInfo = ' (<a target="_blank" href="'+JWB.index_php+'?title='+pagee+'&diff='+info+'">diff</a>)'; actionStat = 'pagesSaved'; } break; case 'nobots': action = 'bot-skip'; extraInfo = ' (<a target="_blank" href="https://en.wikipedia.org/wiki/Template:Bots">{{bots}}</a>)'; // no break; case 'skip': actionStat = 'pagesSkipped'; break; case 'move': extraInfo = ' to <a target="_blank" href="/wiki/'+encodeURIComponent(info)+'" title="'+info+'">'+info+'</a>'; break; case 'protect': extraInfo = info; break; } actionStat = '#' + (actionStat || 'otherActions'); $(actionStat).html(+$(actionStat).html() + 1); $('#actionlog tbody') .append('<tr>'+ '<td>'+(JWB.fn.pad0(d.getHours())+':'+JWB.fn.pad0(d.getMinutes())+':'+JWB.fn.pad0(d.getSeconds()))+'</td>'+ '<th>'+action+'</th>'+ '<td><a target="_blank" href="/wiki/'+pagee+'" title="'+page+'">'+page+'</a>'+ extraInfo +'</td>'+ '</tr>') .parents('.JWBtabc').scrollTop($('#actionlog tbody').parents('.JWBtabc')[0].scrollHeight); }; //Move to the next page in the list JWB.next = function(nextPage) { // cancel any still ongoing regex match/replace functions, since we're moving on to another page. JWB.worker.cancelAll(); if ($.trim(nextPage) && !$('#skipAfterAction').prop('checked')) { nextPage = $.trim(nextPage) + '\n'; } else { nextPage = ''; } $('#articleList').val($('#articleList').val().replace(/^.*\n?/, nextPage)); JWB.list.splice(0,1); JWB.pageCount(); JWB.api.get(JWB.list[0].split('|')[0]); }; //Stop everything, reset inputs and editor JWB.stop = function() { console.trace('stopped'); $('#stopbutton,'+ '.editbutton,'+ '#watchNow,'+ '.JWBtabc[data-tab="2"] .editbutton,'+ '#watchNow'+ '.JWBtabc[data-tab="4"] button,'+ '#skipRETF').prop('disabled', true); $('#startbutton, #articleList,'+ '.JWBtabc[data-tab="1"] button,'+ '#replacesPopup button,'+ '#replacesPopup input,'+ '.JWBtabc input, select').prop('disabled', false); $('#resultWindow').html(''); $('#editBoxArea').val(''); $('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' ')); JWB.pl.done = true; JWB.pl.stop(); JWB.status('done', true); JWB.isStopped = true; }; //Start AutoWikiBrowsing JWB.start = function() { JWB.pageCount(); JWB.listReplaces(); // generate list of replacements to make if (JWB.list.length === 0 || (JWB.list.length === 1 && !JWB.list[0])) { alert(JWB.msg('no-pages-listed')); } else if ($('#skipNoChange').prop('checked') && JWB.replaces.length === 0 && !$('#enableRETF').prop('checked')) { alert(JWB.msg('infinite-skip-notice')); } else { JWB.isStopped = false; if ($('#preparse').prop('checked')) { if (!$('#articleList').val().match('#PRE-PARSE-STOP')) { $('#articleList').val($.trim($('#articleList').val()) + '\n#PRE-PARSE-STOP'); //mark where to stop pre-parsing } } else { $('#preparse-reset').click(); } $('#stopbutton, .editbutton, #watchNow, .JWBtabc[data-tab="2"] button, .JWBtabc[data-tab="4"] button, #skipRETF').prop('disabled', false); $('#startbutton, #articleList, .JWBtabc[data-tab="1"] button, #replacesPopup button, #replacesPopup input, .JWBtabc input, select').prop('disabled', true); if (!JWB.bot || !$('#autosave').prop('checked')) { // keep summary / watchlist options enabled when not in autosave mode $('#minorEdit, #summary, #viaJWB, #watchPage').prop('disabled', false); } JWB.api.get(JWB.list[0].split('|')[0]); } }; JWB.updateButtons = function() { if (!JWB.page.exists && $('#deletePage').is('.delete')) { $('#deletePage').removeClass('delete').addClass('undelete').html(JWB.msg('editbutton-undelete')); JWB.fn.blink('#deletePage'); //Indicate the button has changed } else if (JWB.page.exists && $('#deletePage').is('.undelete')) { $('#deletePage').removeClass('undelete').addClass('delete').html(JWB.msg('editbutton-delete')); JWB.fn.blink('#deletePage'); //Indicate the button has changed } if (!JWB.page.exists) { $('#movePage').prop('disabled', true); } else { $('#movePage').prop('disabled', false); } $('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) ); }; /***** Web Worker functions *****/ JWB.worker.supported = !!window.Worker; // if window.Worker exists, we can use workers. Unless CSP blocks us. JWB.worker.queue = []; // Load function required to properly load the worker, since directly using `new Worker(url)` for cross-origin URLs does not work even with CORS/CSP rules all allowing it. // See https://stackoverflow.com/q/66188950/1256925 for this exact question JWB.worker.load = function(callback) { if (JWB.worker.blob) return callback(); // already successfully built $.getScript(JWB.imports['worker.js'], function() { // Firefox does not understand try..catch for content security policy violations, so define the worker functions regardless of the blob support. JWB.worker.functions = JWB.worker.function(); // the loaded script just defined JWB.worker.function; convert it to a blob url // Based on https://stackoverflow.com/a/33432215/1256925 if (JWB.worker.supported) try { let blob = new Blob(['('+JWB.worker.function.toString()+')()'], {type: 'text/javascript'}); JWB.worker.blob = URL.createObjectURL(blob); callback(); } catch(e) { if (e.code == 18) { JWB.worker.supported = false; } } }); }; // Create a worker to be able to preform regex operations without hanging the current process. // Based on https://stackoverflow.com/q/66153487/1256925 JWB.worker.init = function() { JWB.worker.load(function() { JWB.worker.worker = new Worker(JWB.worker.blob); JWB.worker.callback = undefined; // explicitly set to the implicit value of undefined. JWB.worker.timeout = 0; JWB.worker.queue = []; JWB.worker.worker.onmessage = function(e) { clearTimeout(JWB.worker.timeout); JWB.worker.timeout = 0; if (JWB.isStopped) { // we're stopped; clear the queue and stop. JWB.worker.queue = []; } else if (JWB.worker.callback !== undefined) { JWB.worker.callback(e.data.result, e.data.err); } else { console.error("Worker finished without callback set:", e.data, e); } JWB.worker.next(true); }; }); }; // Boolean; check if the worker is currently occupied. JWB.worker.isWorking = function() { return JWB.worker.callback !== undefined; }; // Cancel current worker's task (e.g. due to timeout) JWB.worker.terminate = function() { console.log('terminating'); let w = JWB.worker; w.worker.terminate(); w.callback(undefined, 'Timeout exceeded'); let queue = w.queue; // save old queue w.init(); // re-init this worker, since the previous one is presumed dead (and terminated). w.queue = queue; // restore queue }; // Cancel all workers (e.g. due to no longer needing the worker's queued services) JWB.worker.cancelAll = function() { JWB.worker.queue = []; if (JWB.worker.worker) JWB.worker.worker.terminate(); // do not call the callback. }; // Set worker to work, or queue the worker task. JWB.worker.do = function(msg, callback) { if (JWB.worker.isWorking()) { JWB.worker.queue.push({msg: msg, callback: callback}); } else { var timelimit = parseInt($('#timelimit').val()) || 3000; JWB.worker.callback = callback; // Expand "JWB.string" into JWB['string']; to allow the string to be loaded at execution time instead of queue time. // Start with 3x ~ because that cannot exist as the start of an actual page if (msg.str && msg.str.indexOf('~'+'~~JWB.') === 0) msg.str = JWB[msg.str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.worker.postMessage(msg); JWB.worker.timeout = setTimeout(function() { if (!JWB.worker.isWorking()) { console.error('Worker error'); JWB.worker.next(true); return; } JWB.worker.terminate(); JWB.worker.next(true); }, timelimit); } }; // Execute the next task in the queue JWB.worker.next = function(force = false) { if (force) { // force means the function that's calling next() has handled the previous worker task. Clean up after it. JWB.worker.callback = undefined; } else if (JWB.worker.isWorking()) { // still working and the calling function did not specify proper exit of the previous task yet. return false; } if (JWB.worker.queue.length === 0) return true; var q = JWB.worker.queue.shift(); JWB.worker.do(q.msg, q.callback); }; /***** Functions using workers *****/ JWB.worker.match = function(str, pattern, flags, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'match', str, pattern, flags}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.match(str, pattern, flags, callback); } }; JWB.worker.replace = function(str, pattern, flags, rWith, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'replace', str, pattern, flags, rWith}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.replace(str, pattern, flags, rWith, callback); } }; JWB.worker.unparsedReplace = function(str, pattern, flags, rWith, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'unparsedreplace', str, pattern, flags, rWith}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.unparsedreplace(str, pattern, flags, rWith, callback); } }; /***** General functions *****/ //Clear all existing timers to prevent them from getting errors JWB.fn.clearAllTimeouts = function() { var i = setTimeout(function() { return void(0); }, 1000); for (var n=0;n<=i;n++) { clearTimeout(n); clearInterval(n); } console.log('Cleared all running intervals up to index',i); }; //Filter an array to only contain unique values. JWB.fn.uniques = function(arr) { var a = []; for (var i=0, l=arr.length; i<l; i++) { if (a.indexOf(arr[i]) === -1 && arr[i] !== '') { a.push(arr[i]); } } return a; }; // code taken directly from [[Template:Bots]] and changed structurally (not functionally) for readability. The user in this case is "JWB" to deny this script. // the user parameter is still kept as an optional parameter to maintain functionality as given on that template page. JWB.fn.allowBots = function(text, user = "JWB") { var usr = user.replace(/([\(\)\*\+\?\.\-\:\!\=\/\^\$])/g, "\\$1"); if (!new RegExp("\\{\\{\\s*(nobots\\s*\\}\\}|bots\\s*(?:\\}\\}|\\|))", "i").test(text)) return true; if (new RegExp("\\{\\{\\s*bots\\s*\\|\\s*deny\\s*=\\s*([^}]*,\\s*)*" + usr + "\\s*(?=[,\\}])[^}]*\\s*\\}\\}", "i").test(text)) return false; else return new RegExp("\\{\\{\\s*((?!nobots)|bots(\\s*\\|\\s*allow\\s*=\\s*((?!none)|([^}]*,\\s*)*" + usr + "\\s*(?=[,\\}])[^}]*|all))?|bots\\s*\\|\\s*deny\\s*=\\s*(?!all)[^}]*|bots\\s*\\|\\s*optout=(?!all)[^}]*)\\s*\\}\\}", "i").test(text); }; //Prepends zeroes until the number has the desired length of len (default 2) JWB.fn.pad0 = function(n, len = 2) { n = n.toString(); return n.length < len ? Array(len-n.length+1).join('0')+n : n; }; JWB.fn.blink = function(el,t) { t=t?t:500; $(el).prop('disabled', true) .children().animate({opacity:'0.1'},t-100) .animate({opacity:'1'},t) .animate({opacity:'0.1'},t-100) .animate({opacity:'1'},t); setTimeout("$('"+el+"').prop('disabled', false)",t*4-400); }; JWB.fn.setSelection = function(el, start, end, dir) { dir = dir||'none'; //Default value end = end||start; //If no end is specified, assume the caret is placed without creating text selection. if (el.setSelectionRange) { el.focus(); el.setSelectionRange(start, end, dir); } else if (el.createTextRange) { var rng = el.createTextRange(); rng.collapse(true); rng.moveStart('character', start); rng.moveEnd('character', end); rng.select(); } }; JWB.fn.scrollSelection = function(el, index) { //function to fix scrolling to selection - doesn't do that automatically. var newEl = document.createElement('textarea'); //create a new textarea to simulate the same conditions var elStyle = getComputedStyle(el); newEl.style.height = elStyle.height; //copy over size-influencing styles newEl.style.width = elStyle.width; newEl.style.lineHeight = elStyle.lineHeight; newEl.style.fontSize = elStyle.fontSize; newEl.value = el.value.substr(0,index); document.body.appendChild(newEl); //needs to be added to the HTML for the scrollHeight and clientHeight to work. if (newEl.scrollHeight != newEl.clientHeight) { el.scrollTop = newEl.scrollHeight - 2; } else { el.scrollTop = 0; } newEl.remove(); //clean up the mess I've made }; //i18n function JWB.msg = function(message) { var args = arguments; var lang = JWB.lang; if (typeof message === 'object') { lang = message[1]; message = message[0]; } if (lang == 'qqx') return message; if (!JWB.messages || !JWB.messages.en) return '\u29FC'+message+'\u29FD'; // same surrounding <> as used in mw.msg(); var msg; if (JWB.messages.hasOwnProperty(lang) && JWB.messages[lang].hasOwnProperty(message)) { msg = JWB.messages[lang][message]; } else { msg = (JWB.messages.en.hasOwnProperty(message)) ? JWB.messages.en[message] : '\u29FC'+message+'\u29FD'; } msg = msg.replace(/\$(\d+)/g, function(match, num) { return args[+num] || match; }); return msg; }; /***** Init *****/ // Check whether or not we are ready to init JWB. If not allowed, abort and delete JWB object to deny access. JWB.checkInit = function() { if (JWB.allowed === false) { var msg = JWB.msg('not-on-list'); JWB = false; delete JWB; alert(msg); return; } JWB.allLoaded = true; for (var m in JWB.messages) if (JWB.messages[m] === null) JWB.allLoaded = false; if (JWB.allowed === true && JWB.allLoaded && Object.keys(JWB.messages).length == JWB.langs.length + 1) { // if there are two languages to load, wait for them both. console.log('langs loaded'); JWB.init(); //init if verification has already returned true } }; // Initialise JWB JWB.init = function() { console.log(JWB.messages.en, !!JWB.messages.en); JWB.setup.load(); JWB.worker.init(); JWB.fn.clearAllTimeouts(); var findreplace = '<div class="replaces">'+ '<label style="display:block;">'+JWB.msg('label-replace')+' <input type="text" class="replaceText"/></label>'+ '<label style="display:block;">'+JWB.msg('label-rwith')+' <input type="text" class="replaceWith"/></label>'+ '<div class="regexswitch">'+ '<label><input type="checkbox" class="useRegex"> '+JWB.msg('label-useregex')+'</label>'+ '<a class="infoLink" href="http://regex101.com/#javascript" target="_blank" tabindex="-1">101</a>'+ '<label class="divisor" title="'+JWB.msg('tip-regex-flags')+'" style="display:none;">'+ JWB.msg('label-regex-flags')+' <input type="text" class="regexFlags" value="g"/>'+ //default: global replacement '</label>'+ '<br/>'+ '</div>'+ '<label title="'+JWB.msg('tip-ignore-comment')+'">'+ '<input type="checkbox" class="ignoreNowiki"> '+JWB.msg('label-ignore-comment')+ '</label>'+ '</div>'; var NSList = '<select multiple name="namespace" id="namespacelist">'; for (var i in JWB.ns) { if (parseInt(i) < 0) continue; //No Special: or Media: in the list NSList += '<option value="'+JWB.ns[i].id+'" selected>'+(JWB.ns[i]['*'] || '('+JWB.msg('namespace-main')+')')+'</option>'; } NSList += '</select>'; /***** Interface *****/ document.title = 'AutoWikiBrowser Script'+(document.title.split('-')[1] ? ' -'+document.title.split('-')[1] : ''); $('body').html( '<article id="resultWindow"></article>'+ '<main id="inputsWindow">'+ '<div id="inputsBox">'+ '<aside id="articleBox">'+ '<b>'+JWB.msg('pagelist-caption')+'</b>'+ '<textarea id="articleList"></textarea>'+ '</aside>'+ '<section id="tabs">'+ '<nav class="tabholder">'+ '<span class="JWBtab active" data-tab="1">'+JWB.msg('tab-setup')+'</span> '+ '<span class="JWBtab" data-tab="2">'+JWB.msg('tab-editing')+'</span> '+ '<span class="JWBtab" data-tab="3">'+JWB.msg('tab-skip')+'</span> '+ (JWB.sysop?'<span class="JWBtab" data-tab="4">'+JWB.msg('tab-other')+'</span> ':'')+ ' <span class="JWBtab log" data-tab="5">'+JWB.msg('tab-log')+'</span> '+ '</nav>'+ '<section class="JWBtabc active" data-tab="1"></section>'+ '<section class="JWBtabc" data-tab="2"></section>'+ '<section class="JWBtabc" data-tab="3"></section>'+ (JWB.sysop?'<section class="JWBtabc" data-tab="4"></section>':'')+ '<section class="JWBtabc log" data-tab="5"></section>'+ '<footer id="status">done</footer>'+ '</section>'+ '<aside id="editBox">'+ '<b>'+JWB.msg('editbox-caption')+' - <span id="currentpage">'+JWB.msg('editbox-currentpage', ' ', ' ')+'</span></b>'+ '<textarea id="editBoxArea" accesskey=","></textarea>'+ '</aside>'+ '</div>'+ '</main>'+ '<footer id="stats">'+ JWB.msg('stat-pages')+' <span id="totPages">0</span>;&emsp;'+ JWB.msg('stat-save')+' <span id="pagesSaved">0</span>;&emsp;'+ JWB.msg('stat-null')+' <span id="nullEdits">0</span>;&emsp;'+ JWB.msg('stat-skip')+' <span id="pagesSkipped">0</span>;&emsp;'+ JWB.msg('stat-other')+' <span id="otherActions">0</span>;&emsp;'+ '</footer>'+ '<div id="overlay" style="display:none;"></div>'+ '<section class="JWBpopup" id="replacesPopup" style="display:none;">'+ '<button class="moreReplaces" data-insert="after">'+JWB.msg('button-more-fields')+'</button>'+ '<br>'+findreplace+ '<button class="moreReplaces" data-insert="before">'+JWB.msg('button-more-fields')+'</button>'+ '</section>'+ '<section class="JWBpopup" id="pagelistPopup" style="display:none;">'+ '<form action="#" id="pl-form"></form>'+ '</section>' ); $('.JWBtabc[data-tab="1"]').html( '<fieldset id="pagelist">'+ '<legend>'+JWB.msg('label-pagelist')+'</legend>'+ '<button id="removeDupes">'+JWB.msg('button-remove-dupes')+'</button> '+ '<button id="sortArticles">'+JWB.msg('button-sort')+'</button>'+ '<br>'+ '<label title="'+JWB.msg('tip-preparse')+'">'+ '<input type="checkbox" id="preparse"> '+JWB.msg('preparse')+ '</label>'+ '<span class="divisor"></span>'+ '<button id="preparse-reset" title="'+JWB.msg('tip-preparse-reset')+'">'+JWB.msg('preparse-reset')+'</button>'+ '<br>'+ '<button id="pagelistButton">'+JWB.msg('pagelist-generate')+'</button>'+ '</fieldset>'+ '<fieldset id="settings">'+ '<legend>'+JWB.msg('label-settings')+'</legend>'+ '<button id="saveAs" title="'+JWB.msg('tip-store-setup')+'">'+JWB.msg('store-setup')+'</button>'+ '<br>'+ '<label>'+ JWB.msg('load-settings') + ' '+ '<select id="loadSettings">'+ '<option value="default" selected>default</option>'+ '<option value="_blank">'+JWB.msg('blank-setup')+'</option>'+ '</select>'+ '</label>'+ '<span class="divisor"></span>'+ '<button id="deleteSetup" title="'+JWB.msg('tip-delete-setup')+'">'+JWB.msg('delete-setup')+'</button>'+ '<hr>'+ '<button id="saveToWiki">'+JWB.msg('save-setup')+'</button>'+ '<span class="divisor"></span>'+ '<button id="download">'+JWB.msg('download-setup')+'</button>'+ '<hr>'+ '<label class="button" id="importLabel" title="'+JWB.msg('tip-import-setup')+'">'+ '<input type="file" id="import" accept=".json">'+ JWB.msg('import-setup')+ '</label>'+ '<span class="divisor"></span>'+ '<button id="updateSetups" title="'+JWB.msg('tip-update-setup', JWB.settingspage)+'">'+JWB.msg('update-setup')+'</button>'+ '<div id="downloads">'+ '<a download="JWB-settings.json" target="_blank" id="download-anchor"></a>'+ '<iframe id="download-iframe"></iframe>'+ '</div>'+ '</fieldset>'+ '<fieldset id="limits">'+ '<legend>'+JWB.msg('label-limits')+'</legend>'+ '<label class="timelimit-label" title="'+JWB.msg('tip-time-limit')+'">'+ JWB.msg('time-limit')+ '<input type="number" id="timelimit" value="3000" min="0">'+ '</label>'+ '<label title="'+JWB.msg('tip-diff-size-limit')+'">'+ JWB.msg('diff-size-limit')+ '<input type="number" id="sizelimit" value="0" min="0">'+ '</label>'+ '</fieldset>' ); $('.JWBtabc[data-tab="2"]').html( '<label class="minorEdit"><input type="checkbox" id="minorEdit" accesskey="i" checked> '+JWB.msg('minor-edit')+'</label>'+ '<label class="editSummary'+(JWB.hasTag?'':' viaJWB')+'">'+JWB.msg('edit-summary')+'<br/> <input class="fullwidth" type="text" id="summary" maxlength="500" accesskey="b"></label>'+ ' <input type="checkbox" id="viaJWB"'+(JWB.hasTag?'':' checked')+' title="'+JWB.msg('tip-via-JWB')+'">'+ '<select id="watchPage">'+ '<option value="watch">'+JWB.msg('watch-watch')+'</option>'+ '<option value="unwatch">'+JWB.msg('watch-unwatch')+'</option>'+ '<option value="nochange" selected>'+JWB.msg('watch-nochange')+'</option>'+ '<option value="preferences">'+JWB.msg('watch-preferences')+'</option>'+ '</select>'+ '<span class="divisor"></span>'+ '<button id="watchNow" disabled accesskey="w">'+ JWB.msg('watch-add')+ '</button>'+ '<br>'+ (JWB.bot? '<label><input type="checkbox" id="autosave"> '+JWB.msg('auto-save')+'</label>'+ '<label title="'+JWB.msg('tip-save-interval')+'" class="divisor">'+ JWB.msg('save-interval', '<input type="number" min="0" value="0" style="width:50px" id="throttle" disabled>')+ '</label>'+ '<br>' :'')+ '<label style="display:block">'+ JWB.msg('on-load')+ ' <select id="onLoad">'+ '<option value="diff" selected>'+JWB.msg('on-load-diff')+'</option>'+ '<option value="preview">'+JWB.msg('on-load-preview')+'</option>'+ '</select>'+ '</label>'+ '<hr>'+ '<span id="startstop">'+ '<button id="startbutton" accesskey="a">'+JWB.msg('editbutton-start')+'</button>'+ '<br>'+ '<button id="stopbutton" disabled accesskey="q">'+JWB.msg('editbutton-stop')+'</button> '+ '</span>'+ '<button class="editbutton" id="skipButton" disabled accesskey="n">'+JWB.msg('editbutton-skip')+'</button>'+ '<button class="editbutton" id="submitButton" disabled accesskey="s">'+JWB.msg('editbutton-save')+'</button>'+ '<br>'+ '<button class="editbutton" id="previewButton" disabled accesskey="p">'+JWB.msg('editbutton-preview')+'</button>'+ '<button class="editbutton" id="diffButton" disabled accesskey="d">'+JWB.msg('editbutton-diff')+'</button>'+ '<button id="replacesButton">'+JWB.msg('button-open-popup')+'</button>'+ findreplace+ '<hr>'+ '<label><input type="checkbox" id="enableRETF"> '+ JWB.msg('label-enable-RETF', '<a href="/wiki/Project:AutoWikiBrowser/Typos" target="_blank">'+ JWB.msg('label-RETF')+ '</a>')+ '</label>'+ ' <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Gnome-view-refresh.svg/20px-Gnome-view-refresh.svg.png"'+ 'id="refreshRETF" title="'+JWB.msg('tip-refresh-RETF')+'">'+ '<br/>'+ '<button id="skipRETF" title="'+JWB.msg('tip-skip-RETF')+'" disabled>'+JWB.msg('skip-RETF')+'</button>' ); $('.JWBtabc[data-tab="3"]').html( '<fieldset>'+ '<legend>'+JWB.msg('label-redirects')+'</legend>'+ '<label title="'+JWB.msg('tip-redirects-follow')+'">'+ '<input type="radio" class="redirects" value="follow" name="redir" id="redir-follow"> '+JWB.msg('redirects-follow')+' '+ '</label>'+ '<label title="'+JWB.msg('tip-redirects-skip')+'">'+ '<input type="radio" class="redirects" value="skip" name="redir" id="redir-skip"> '+JWB.msg('redirects-skip')+' '+ '</label>'+ '<label title="'+JWB.msg('tip-redirects-edit')+'">'+ '<input type="radio" class="redirects" value="edit" name="redir" id="redir-edit" checked> '+JWB.msg('redirects-edit')+''+ '</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('label-skip-when')+'</legend>'+ '<label><input type="checkbox" id="skipNoChange"> '+JWB.msg('skip-no-change')+'</label>'+ '<br>'+ '<label><input type="radio" id="exists-yes" name="exists" value="yes"> '+JWB.msg('skip-exists-yes')+'</label> '+ '<label><input type="radio" id="exists-no" name="exists" value="no" checked> '+JWB.msg('skip-exists-no')+'</label> '+ '<label><input type="radio" id="exists-neither" name="exists" value="neither"> '+JWB.msg('skip-exists-neither')+'</label>'+ (JWB.sysop?'<br><label><input type="checkbox" id="skipAfterAction" checked> '+JWB.msg('skip-after-action')+'</label>':'')+ '<hr/>'+ '<label>'+JWB.msg('skip-contains')+' <input class="fullwidth" type="text" id="skipContains"></label>'+ '<label>'+JWB.msg('skip-not-contains')+' <input class="fullwidth" type="text" id="skipNotContains"></label>'+ '<div class="regexswitch">'+ '<label><input type="checkbox" id="containRegex"> '+JWB.msg('label-useregex')+'</label>'+ '<a class="re101" href="http://regex101.com/#javascript" target="_blank">?</a>'+ '<label class="divisor" title="'+JWB.msg('tip-regex-flags')+'" style="display:none;">'+ JWB.msg('label-regex-flags')+' <input type="text" id="containFlags"/>'+ '</label>'+ '</div>'+ '<hr/>'+ '<label title="'+JWB.msg('skip-cg-prefix')+'">'+JWB.msg('skip-category')+' <input class="fullwidth" type="text" id="skipCategories"></label>'+ '</fieldset>' ); if (JWB.sysop) $('.JWBtabc[data-tab="4"]').html( '<fieldset>'+ '<legend>'+JWB.msg('move-header')+'</legend>'+ '<label><input type="checkbox" id="suppressRedir"> '+JWB.msg('move-redir-suppress')+'</label>'+ '<br>'+ JWB.msg('move-also')+' '+ '<label><input type="checkbox" id="movetalk"> '+JWB.msg('move-talk-page')+'</label> '+ '<label><input type="checkbox" id="movesubpage"> '+JWB.msg('move-subpage')+'</label>'+ '<br>'+ '<label>'+JWB.msg('move-new-name')+' <input type="text" id="moveTo"></label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('delete-header')+'</legend>'+ '<label><input type="checkbox" id="deleteTalk"> '+JWB.msg('delete-talk')+'</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('protect-header')+'</legend>'+ JWB.msg('protect-edit')+ ' <select id="editProt">'+ '<option value="all" selected>'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ JWB.msg('protect-move')+ ' <select id="moveProt">'+ '<option value="" selected>('+JWB.msg('protect-like-edit')+')</option>'+ '<option value="all">'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ JWB.msg('protect-upload')+ ' <select id="uploadProt">'+ '<option value="" selected>('+JWB.msg('protect-like-edit')+')</option>'+ '<option value="all">'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ '<label>'+JWB.msg('protect-expiry')+'<a class="infoLink" href="https://www.mediawiki.org/w/api.php?action=help&modules=main#main/datatypes" target="_blank" tabindex="-1">?</a> <input type="text" id="protectExpiry"/></label>'+ '</fieldset>'+ '<button id="movePage" disabled accesskey="m">'+JWB.msg('editbutton-move')+'</button> '+ '<button id="deletePage" class="delete" disabled accesskey="x">'+JWB.msg('editbutton-delete')+'</button> '+ '<button id="protectPage" disabled accesskey="z">'+JWB.msg('editbutton-protect')+'</button> '+ '<button id="skipPage" disabled title="['+JWB.tooltip+'n]">'+JWB.msg('editbutton-skip')+'</button>'+ '<div class="logActionNote">'+JWB.msg('log-action-note')+'</div>' ); $('.JWBtabc[data-tab="5"]').html('<table id="actionlog"><tbody></tbody></table>'); $('#pagelistPopup form').html( '<div id="ns-filter" title="'+JWB.msg('tip-ns-select')+'">' + JWB.msg('label-ns-select') + NSList + '</div>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="categorymembers" name="categorymembers" value="cm"> '+JWB.msg('legend-cm')+'</label></legend>'+ '<label title="'+JWB.msg('tip-cm')+'">'+JWB.msg('label-cm')+' <input type="text" name="cmtitle" id="cmtitle" class="fullwidth"></label>'+ '<div>'+JWB.msg('cm-include')+' '+ '<label><input type="checkbox" id="cmtype-page" name="cmtype" value="page" checked> '+JWB.msg('cm-include-pages')+'</label>'+ '<label><input type="checkbox" id="cmtype-subcg" name="cmtype" value="subcat" checked> '+JWB.msg('cm-include-subcgs')+'</label>'+ '<label><input type="checkbox" id="cmtype-file" name="cmtype" value="file" checked> '+JWB.msg('cm-include-files')+'</label>'+ '</div>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" name="linksto" id="linksto"> '+JWB.msg('legend-linksto')+'</label></legend>'+ '<label>'+JWB.msg('label-linksto')+' <input type="text" name="title" id="linksto-title" class="fullwidth"></label>'+ '<div>'+JWB.msg('links-include')+' '+ '<label><input type="checkbox" id="backlinks" name="backlinks" value="bl" checked> '+JWB.msg('links-include-links')+'</label>'+ '<label><input type="checkbox" id="embeddedin" name="embeddedin" value="ei"> '+JWB.msg('links-include-templ')+'</label>'+ '<label><input type="checkbox" id="imageusage" name="imageusage" value="iu"> '+JWB.msg('links-include-files')+'</label>'+ '</div>'+ '<div>'+JWB.msg('links-redir')+' '+ '<label><input type="radio" id="rfilter-redir" name="filterredir" value="redirects"> '+JWB.msg('links-redir-redirs')+'</label>'+ '<label><input type="radio" id="rfilter-nonredir" name="filterredir" value="nonredirects"> '+JWB.msg('links-redir-noredirs')+'</label>'+ '<label><input type="radio" id="rfilter-all" name="filterredir" value="all" checked> '+JWB.msg('links-redir-all')+'</label>'+ '</div>'+ '<label title="'+JWB.msg('tip-link-redir')+'">'+ '<input type="checkbox" name="redirect" value="true" checked id="linksto-redir"> '+JWB.msg('label-link-redir')+ '</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="prefixsearch" name="prefixsearch" value="ps"> '+JWB.msg('legend-ps')+'</label></legend>'+ '<label>'+JWB.msg('label-ps')+' <input type="text" name="pssearch" id="pssearch" class="fullwidth"></label>'+ '<label title="'+JWB.msg('tip-ps-strict')+'"><input type="checkbox" name="allpages" value="ap" id="psstrict" checked> '+JWB.msg('label-ps-strict')+'</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="watchlistraw" name="watchlistraw" value="wr"> '+JWB.msg('legend-wr')+'</label></legend>'+ JWB.msg('label-wr')+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="proplinks" name="links" value="pl"> '+JWB.msg('legend-pl')+'</label></legend>'+ '<label title="'+JWB.msg('tip-pl')+'">'+JWB.msg('label-pl')+' <input type="text" id="titles" name="titles" class="fullwidth"></label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="proplinks" name="search" value="sr"> '+JWB.msg('legend-sr')+'</label></legend>'+ '<label title="'+JWB.msg('tip-sr')+'\n'+JWB.msg('placeholder-sr', 'insource:', 'intitle:')+'">'+ JWB.msg('label-sr')+ ' <input type="text" id="srsearch" name="srsearch" class="fullwidth" placeholder="'+JWB.msg('placeholder-sr', 'insource:', 'intitle:')+'">'+ '</label>'+ '</fieldset>'+ '<fieldset class="listSMW">'+ '<legend><label><input type="checkbox" id="smwask" name="smwask" value="smw"> '+JWB.msg('legend-smw', JWB.msg('smw-slow'))+'</label></legend>'+ '<textarea id="smwquery" name="smwquery" placeholder="'+JWB.msg('label-smw', '\n|limit=500')+'"></textarea>'+ '</fieldset>'+ '<button type="submit">'+JWB.msg('pagelist-generate')+'</button>' ); if (JWB.hasSMW) { $('#pagelistPopup').addClass('hasSMW'); } $('body').addClass('AutoWikiBrowser').addClass('notheme'); //allow easier custom styling of JWB. $('[accesskey]').each(function() { let lbl = this.accessKeyLabel || this.accessKey; // few browsers support accessKeyLabel, so fallback to accessKey. $(this).attr('title', '['+lbl+']'); }); /***** Setup *****/ JWB.setup.save('_blank'); //default setup if (JWB.settings.hasOwnProperty('default')) { JWB.setup.apply(); } else if (JWB.setup.initialised) { // If we already initialised, create the default settings profile. JWB.setup.save('default'); } JWB.setup.extend({}); /***** Event handlers *****/ //Alert user when leaving the tab, to prevent accidental closing. onbeforeunload = function() { return "Closing this tab will cause you to lose all progress."; }; ondragover = function(e) { e.preventDefault(); }; document.addEventListener("securitypolicyviolation", function(e) { console.log('violated CSP:', e); if (e.blockedURI == 'blob') { JWB.worker.supported = false; // tell the next JWB.worker.init() that it shouldn't even try. } else if (JWB && JWB.msg) { alert(JWB.msg('csp-error', e.violatedDirective)); } }); $('.JWBtab').click(function() { $('.active').removeClass('active'); $(this).addClass('active'); $('.JWBtabc[data-tab="'+$(this).attr('data-tab')+'"]').addClass('active'); }); function showRegexFlags() { // >>this<< is the element that's triggered $(this).parent().nextAll('label').toggle(this.checked); } $('body').on('change', '#useRegex, #containRegex, .useRegex', showRegexFlags); $('#preparse-reset').click(function() { $('#articleList').val($('#articleList').val().replace(/#PRE-PARSE-STOP/g,'').replace(/\n\n/g, '\n')); }); $('#saveAs').click(function() { JWB.setup.save(); }); $('#loadSettings').change(function() { JWB.setup.apply(this.value); }); $('#download').click(JWB.setup.download); $('#saveToWiki').click(JWB.setup.submit); $('#import').change(JWB.setup.import); ondrop = JWB.setup.import; $('#updateSetups').click(JWB.setup.load); $('#deleteSetup').click(JWB.setup.del); if (window.RETF) { $('#refreshRETF').click(RETF.load); $('#skipRETF').click(JWB.skipRETF); $('#enableRETF').change(function() { $('#skipRETF').css('visibility', this.checked ? 'visible' : 'hidden'); }); } $('#replacesButton, #pagelistButton').click(function() { var popup = this.id.slice(0, -6); //omits the 'Button' in the id by cutting off the last 6 characters $('#'+popup+'Popup, #overlay').show(); }); $('#overlay').click(function() { $('#replacesPopup, #pagelistPopup, #overlay').hide(); JWB.listReplaces(); JWB.pl.done = true; JWB.pl.stop(); }); $('.moreReplaces').click(function() { var location = $(this).data('insert'); // either call $(this).before() or $(this).after() $(this)[location](findreplace); }); $('#replacesPopup').on('keydown', '.replaces:last', function(e) { if (e.which === 9) $('.moreReplaces[data-insert="before"]')[0].click(); }); $('#pl-form').submit(function(e) { e.preventDefault(); JWB.pl.generate(); return false; }); $('#pagelistPopup legend input').change(function() { //remove disabled attr when checked, add when not. $(this).parents('fieldset').find('input').not('legend input').prop('disabled', !this.checked); $(this).parents('fieldset').prop('disabled', !this.checked); }).trigger('change'); $('#psstrict').change(function() { if (this.checked) { $('#pssearch').attr('name', 'apprefix'); } else { $('#pssearch').attr('name', 'pssearch'); } }).trigger('change'); $('#resultWindow').on('click', 'tr[data-line]:not(.lineheader) *', function(e) { var line = +$(e.target).closest('tr[data-line]').data('line'); var index = $('#editBoxArea').val().split('\n').slice(0, line-1).join('\n').length; $('#editBoxArea')[0].focus(); JWB.fn.setSelection($('#editBoxArea')[0], index+1); JWB.fn.scrollSelection($('#editBoxArea')[0], index); }); $('#removeDupes').click(function() { $('#articleList').val(JWB.fn.uniques($('#articleList').val().split('\n')).join('\n')); JWB.pageCount(); }); $('#sortArticles').click(function() { $('#articleList').val($('#articleList').val().split('\n').sort().join('\n')); JWB.pageCount(); }); $('#watchNow').click(JWB.api.watch); $('#autosave').change(function() { $('#throttle').prop('disabled', !this.checked); }); $('#viaJWB').change(function() { $('#summary').parent('label') .toggleClass('viaJWB', this.checked) .attr('maxlength', 500 - this.checked*JWB.summarySuffix.length); // Change the max size of the allowed summary according to having a suffix or not. }); $('#startbutton').click(JWB.start); $('#stopbutton').click(JWB.stop); $('#submitButton').click(JWB.api.submit); $('#previewButton').click(JWB.api.preview); $('#diffButton').click(JWB.api.diff); $('#skipButton, #skipPage').click(function() { JWB.log('skip', JWB.list[0].split('|')[0]); JWB.next(); }); if (JWB.sysop) { $('#movePage').click(function() { if ($('#moveTo').val().length === 0) { return alert(JWB.msg('alert-no-move')); } JWB.api.move(); }); $('#protectPage').click(JWB.api.protect); $('#deletePage').click(JWB.api.del); } }; //Disable JWB altogether when it's loaded on a page other than Project:AutoWikiBrowser/Script. This script shouldn't be loaded on any other page in the first place. if (JWB.allowed === false) JWB = false; /* JWB sonu */ 0qm5oxqrk8os7ilzl512uo3wkswx0er 240640 240636 2026-10-16T18:20:00Z Brightt11 34669 240640 javascript text/javascript /* JWB başlangıcı */ /** <nowiki> * Install this script by pasting the following in your personal JavaScript file: mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript'); * Or for users on en.wikipedia.org: {{subst:lusc|User:Joeytje50/JWB.js/load.js}} * Note that this script will only run on the 'Project:AutoWikiBrowser/Script' page. * This script is based on the downloadable AutoWikiBrowser. * * @licence * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html * @version 4.5.2 * @author Joeytje50 * </nowiki> */ window.JWBdeadman = false; // ADMINS: in case of fire, set this variable to true to disable this entire tool for all users //TODO: more advanced pagelist-generating options //TODO: generate page list based on images on a page //TODO: Add feature to perform general cleanup (<table> to {|, fullurl-links to wikilinks, removing underscores from wikilinks) //TODO: Add report button to AJAX error alert box //TODO: Re-add errored pages to the page list //TODO: Automatically generate full list of protection levels //TODO: Add 'Ignore quotes' alongside 'Ignore unparsed content'; for example: Ignore [] Unparsed content [] Quotes //TODO: Read wikiquote:AutoWikiBrowser/Config for when not to apply typo fixes //TODO: RETF disable any \b and some other cases //TODO: Fix deletedrevs deprecated API //TODO: Handle response 429 (Too Many Requests) by rate-limiting Pre-parse mode //Cleanup / modernize: // .indexOf('') != -1 -> .includes() // mw for requests, instead of ajax // Optional?.chaining?.properties /***** Global object/variables *****/ window.JWB = {}; //The main global object for the script. (function() { // Easier way to change import location for local debugging etc. JWB.imports = { 'JWB.css': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.css&action=raw&ctype=text/css', 'i18n.js': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/i18n.js&action=raw&ctype=text/javascript', 'i18n': {}, 'RETF.js': '//en.wikipedia.org/w/index.php?title=User:Joeytje50/RETF.js&action=raw&ctype=text/javascript', 'worker.js':'//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/worker.js&action=raw&ctype=text/javascript', }; JWB.allLoaded = false; let objs = ['page', 'api', 'worker', 'fn', 'pl', 'messages', 'setup', 'settings', 'ns']; for (let i=0;i<objs.length;i++) { JWB[objs[i]] = {}; } JWB.summarySuffix = ' (via JWB)'; if (document.location.hostname == 'en.wikipedia.org') JWB.summarySuffix = ' (via [[WP:JWB]])'; JWB.lang = mw.config.get('wgUserLanguage').replace('-', '_'); JWB.contentLang = mw.config.get('wgContentLanguage').replace('-', '_'); JWB.index_php = mw.config.get('wgScript'); JWB.isStopped = true; JWB.tooltip = window.tooltipAccessKeyPrefix || ''; let configext = 'js'; if (document.location.hostname.split('.').slice(-2).join('.') == 'wikia.com' || document.location.hostname.split('.').slice(-2).join('.') == 'fandom.com') { //LEGACY: fallback to settings on css for Wikia; uses JSON now. configext = 'css'; } JWB.settingspage = 'JWB-settings.'+configext; if (window.hasOwnProperty('JWBSETTINGS')) { JWB.settingspage = JWBSETTINGS+'-settings.'+configext; delete window.JWBSETTINGS; //clean up the global variable } JWB.hasJSON = false; // whether or not the wiki supports JSON userpages (mw 1.31+). JWB.hasSMW = false; // whether or not the wiki has SMW installed. })(); /***** User verification *****/ (function() { if (mw.config.get('wgCanonicalNamespace')+':'+mw.config.get('wgTitle') !== 'Project:AutoWikiBrowser/Script' || JWB.allowed === false || mw.config.get('wgUserName') === null) { JWB.allowed = false; return; } mw.loader.load(JWB.imports['JWB.css'], 'text/css'); mw.loader.load('mediawiki.diff.styles'); JWB.langs = []; $.getScript(JWB.imports['i18n.js'], function() { if (JWB.allowed === false) { JWB.checkInit(); // deny access without attempting to load other languages. return; } if (JWB.lang !== 'en' && JWB.imports.i18n.hasOwnProperty(JWB.lang)) { JWB.langs.push(JWB.imports.i18n[JWB.lang]); JWB.messages[JWB.lang] = JWB.messages[JWB.lang] || null; } else if (JWB.lang !== 'en' && JWB.lang !== 'qqx') { // this only happens if the language file does not exist. JWB.lang = 'en'; } if (JWB.contentLang !== 'en' && JWB.contentLang !== JWB.lang && JWB.imports.i18n.hasOwnProperty(JWB.contentLang)) { JWB.langs.push(JWB.imports.i18n[JWB.contentLang]); JWB.messages[JWB.contentLang] = JWB.messages[JWB.contentLang] || null; } if (JWB.langs.length) { $.when.apply($, JWB.langs.map(url => $.getScript(url))).done(function(r) { JWB.checkInit(); }); } else { // no more languages to load. console.log('no languages needed loading'); JWB.checkInit(); } }); //RegEx Typo Fixing $.getScript(JWB.imports['RETF.js'], function() { $('#refreshRETF').click(RETF.load); }); if (window.JWBdeadman === true) { window.JWB = false; // disable all access alert("This tool has been temporarily been disabled by wikiquote admins due to issues it would otherwise cause. Please check back soon to see if it is working again."); return false; } else if (!window.Worker) { // https://caniuse.com/webworkers - this should not happen for any sensible human being. Either you're on IE<10, or you're just testing my patience. alert("Web Workers are not supported in this browser. Please use a more modern browser to use JWB. Most matching and replacing features are not supported in this browser."); } (new mw.Api()).get({ action: 'query', titles: 'Project:AutoWikiBrowser/CheckPageJSON|MediaWiki:Tag-JWB', prop: 'info|revisions', meta: 'userinfo|siteinfo', rvprop: 'content', uiprop: 'groups', siprop: 'namespaces|usergroups|extensions', indexpageids: true, format: 'json', }).done(function(response) { if (response.error) { alert('API error: ' + response.error.info); JWB = false; //preventing further access. No verification => no access. return; } JWB.ns = response.query.namespaces; //saving for later // This will execute before JWB.init() and therefore before JWB.setup.load() loading the user's settings. let wikigroups = response.query.usergroups; for (var u of wikigroups) { if (u.rights.indexOf('edituserjson') !== -1) { JWB.hasJSON = true; break; } } // Check if we've got SMW on this wiki let extensions = response.query.extensions; for (var e of extensions) { if (e.name == "SemanticMediaWiki") { JWB.hasSMW = true; break; } } JWB.username = response.query.userinfo.name; //preventing any "hacks" that change wgUserName or mw.config.wgUserName var groups = response.query.userinfo.groups; var page = Object.values(response.query.pages).find(page => page.title.includes("AutoWikiBrowser/CheckPageJSON")); var tagPage = Object.values(response.query.pages).find(page => page.title.includes("Tag-JWB")); JWB.hasTag = (tagPage.missing === undefined); var users = []; var bots = []; JWB.sysop = groups.indexOf('sysop') !== -1; if (response.query.pageids[0] !== '-1') { var checkPageData = JSON.parse(page.revisions[0]['*']); users = checkPageData.enabledusers; if ("enabledbots" in checkPageData) { bots = checkPageData.enabledbots; } } else { users = false; //fallback when page doesn't exist if (JWB.sysop) { // Check and inform admins if their checkpage is the unsupported format. (new mw.Api()).get({ action: 'query', titles: 'Project:AutoWikiBrowser/CheckPage', prop: 'info', indexpageids: true, }).done(function(oldpage){ var q = oldpage.query; if (q.pageids[0] != '-1' && !q.pages[q.pageids[0]].hasOwnProperty('redirect')) { // CheckPageJSON does not exist, and CheckPage does exist, and is not a redirect. // This indicates the checkpage needs to be ported to JSON. Notify admins. prompt('Warning: The AWB checkpage found at Project:AutoWikiBrowser/CheckPage is no longer supported.\n'+ 'Please convert this checkpage to a JSON checkpage. See the URL below for more information.\n'+ 'After creating the JSON checkpage, you can use "Special:ChangeContentModel" to change the content model to JSON.', 'https://trwikiquote.org/wiki/wikiquote:AutoWikiBrowser/CheckPage_format'); } }); } } JWB.bot = groups.indexOf('bot') !== -1 && (users === false || bots.includes(JWB.username)); // Temporary global debugging variables JWB.debug = [groups.indexOf('bot'), users === false, bots && bots.indexOf(JWB.username)]; if (JWB.username === "Joeytje50" && response.query.userinfo.id === 13299994) {//TEMP: Dev full access to entire interface. JWB.bot = true; users.push("Joeytje50"); } if (JWB.sysop || response.query.pageids[0] === '-1' || users === false || users.includes(JWB.username) || bots.includes(JWB.username)) { JWB.allowed = true; JWB.checkInit(); //init if everything necessary has been loaded } else { if (JWB.allLoaded) { //run this after messages have loaded, so the message that shows is in the user's language alert(JWB.msg('not-on-list')); } JWB = false; //prevent further access } }).fail(function(xhr, error) { alert(JWB.msg('verify-error') + '\n' + error); JWB = false; //preventing further access. No verification => no access. }); })(); /***** API functions *****/ //Main template for API calls JWB.api.call = function(data, callback, onerror) { data.format = 'json'; if (data.action !== 'query' && data.action !== 'compare' && data.action !== 'ask' && data.action !== 'parse' && data.action !== 'watch') { data.bot = true; // mark edits as bot if (JWB.hasTag) data.tags = 'JWB'; // tag with 'JWB' } $.ajax({ data: data, dataType: 'json', url: mw.config.get('wgScriptPath') + '/api.php', type: 'POST', success: function(response) { if (response.error) { if (onerror && onerror(response, 'API') === false) return; alert('API error: ' + response.error.info); JWB.stop(); } else { callback(response); } }, // onerror: if it exists and returns false, do not show error alert. Otherwise, do show alert. error: function(xhr, error) { if (onerror && onerror(error, 'AJAX') === false) return; alert('AJAX error: ' + error); JWB.stop(); } }); }; //Get page diff, and process it for more interactivity JWB.api.diff = function(callback) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('diff'); var editBoxInput = $('#editBoxArea').val(); var redirect = $('input.redirects:checked').val(); var data = { action: 'compare', indexpageids: true, fromtitle: JWB.page.name, //toslots: 'main', // TODO: Once this gets supported more widely, convert to the non-deprecated toslots system. //'totext-main': editBoxInput, totext: editBoxInput, topst: true, }; if (redirect=='follow') data.redirects = true; JWB.api.call(data, function(response) { var diff; diff = response.compare['*']; if (diff === '') { diff = '<h2>'+JWB.msg('no-changes-made')+'</h2>'; } else { diff = '<table class="diff">'+ '<colgroup>'+ '<col class="diff-marker">'+ '<col class="diff-content">'+ '<col class="diff-marker">'+ '<col class="diff-content">'+ '</colgroup>'+ '<tbody>'+diff+'</tbody></table>'; } $('#resultWindow').html(diff); $('.diff-lineno').each(function() { var lineNumMatch = $(this).html().match(/\d+/); if (lineNumMatch) { $(this).parent().attr('data-line',parseInt(lineNumMatch[0])-1).addClass('lineheader'); } }); $('table.diff tr').each(function() { //add data-line attribute to every line, relative to the previous one. Used for click event. if (!$(this).next().is('[data-line]') && !$(this).next().children('td.diff-deletedline + td.diff-empty').length) { $(this).next().attr('data-line',parseInt($(this).data('line'))+1); } else if ($(this).next().children('td.diff-deletedline + td.diff-empty').length) { $(this).next().attr('data-line',$(this).data('line')); //copy over current data-line for deleted lines to prevent them from messing up counting. } }); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } }, function(err, type) { if (type == 'API' && err.error.code == 'missingtitle') { // missingtitle is to be expected when editing a page that doesn't exist; just show a message and move on. $('#resultWindow').html('<span style="font-weight:bold;color:red;">'+JWB.msg('page-not-exists')+'</span>'); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } return false; // stop propagation of error; do not show alerts. } }); }; //Retrieve page contents/info, process them, and store information in JWB.page object. JWB.api.get = function(pagename) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.pageCount(); if (!JWB.list[0] || JWB.isStopped) { return JWB.stop(); } if (pagename === '#PRE-PARSE-STOP') { var curval = $('#articleList').val(); $('#articleList').val(curval.substr(curval.indexOf('\n') + 1)); $('#preparse').prop('checked', false); JWB.stop(); return; } let cgns = JWB.ns[14]['*']; let skipcg = $('#skipCategories').val(); // prepend Category: before all categories and turn CSV(,) into CSV(|). skipcg = skipcg.replace(new RegExp('(^|,|\\|)('+cgns+':)?', 'gi'), '|'+cgns+':').substr(1); var redirect = $('input.redirects:checked').val(); var data = { action: 'query', prop: 'info|revisions|categories', inprop: 'watched|protection', type: 'csrf|watch', titles: pagename, rvprop: 'content|timestamp|ids', rvlimit: '1', cllimit: 'max', clcategories: skipcg, indexpageids: true, meta: 'userinfo|tokens', uiprop: 'hasmsg' }; if (redirect=='follow'||redirect=='skip') data.redirects = true; if (JWB.sysop) { data.list = 'deletedrevs'; } JWB.status('load-page'); JWB.api.call(data, function(response) { if (response.query.userinfo.hasOwnProperty('messages')) { var view = mw.config.get('wgScriptPath') + '?title=Special:MyTalk'; var viewNew = view + '&diff=cur'; JWB.status( '<span style="color:red;font-weight:bold;">'+ JWB.msg('status-newmsg', '<a href="'+view+'" target="_blank">'+JWB.msg('status-talklink')+'</a>', '<a href="'+viewNew+'" target="_blank">'+JWB.msg('status-difflink')+'</a>')+ '</span>', true); alert(JWB.msg('new-message')); JWB.stop(); return; } JWB.page = response.query.pages[response.query.pageids[0]]; JWB.page.token = response.query.tokens.csrftoken; JWB.page.watchtoken = response.query.tokens.watchtoken; JWB.page.name = JWB.list[0].split('|')[0]; var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0; JWB.page.pagevar = JWB.list[0].substr(varOffset); JWB.page.content = JWB.page.revisions ? JWB.page.revisions[0]['*'] : ''; JWB.page.exists = !response.query.pages["-1"]; JWB.page.deletedrevs = response.query.deletedrevs; JWB.page.watched = JWB.page.hasOwnProperty('watched'); JWB.page.protections = JWB.page.restrictiontypes; if (response.query.redirects) { JWB.page.name = response.query.redirects[0].to; } JWB.page.path = mw.config.get('wgArticlePath').replace('$1', encodeURIComponent(JWB.page.name)); // check for skips that can be determined before replacing if (!JWB.fn.allowBots(JWB.page.content, JWB.username) || !JWB.fn.allowBots(JWB.page.content)) { // skip if {{bots}} template forbids editing on this page by user OR by JWB in general JWB.log('nobots', JWB.page.name); return JWB.next(); } else if (JWB.page.categories !== undefined || // skip because of a matching category as passed via clcategories. ($('#exists-no').prop('checked') && !JWB.page.exists) || ($('#exists-yes').prop('checked') && JWB.page.exists) || (redirect==='skip' && response.query.redirects) // variable redirect is defined outside this callback function. ) { // simple skip rules JWB.log('skip', JWB.page.name); return JWB.next(); } // Check skip contains rules. var containRegex = $('#containRegex').prop('checked'), containFlags = $('#containFlags').val(); var skipContains, skipNotContains; if (containRegex) { JWB.status('check-skips'); var skipping = false; // for tracking if match is found in synchronous calls. if ($('#skipContains').val().length) { JWB.worker.match(JWB.page.content, $('#skipContains').val(), containFlags, function(result, err) { console.log('Contains', result, err); if (result !== null && err === undefined) { JWB.log('skip', JWB.page.name); JWB.next(); // next() also cancels the skipNotContains. skipping = true; return; } // else continue with the queued worker job that checks skipNotContains }); } if (skipping) { console.log('skipped page before replaces'); return; } if ($('#skipNotContains').val().length) { JWB.worker.match(JWB.page.content, $('#skipNotContains').val(), containFlags, function(result, err) { console.log('Not contains', result, err); if (result === null && err === undefined) { JWB.log('skip', JWB.page.name); JWB.next(); // also cancels the replace skipping = true; return; } // else move on to replacing }); } if (skipping) { console.log('skipped page before replaces'); return; } } else { skipContains = $('#skipContains').val(); skipNotContains = $('#skipNotContains').val(); if ((skipContains && JWB.page.content.includes(skipContains)) || (skipNotContains && !JWB.page.content.includes(skipNotContains))) { console.log('skipped page before replaces'); return JWB.next(); } JWB.status('done', true); } JWB.replace(JWB.page.content, function(newContent) { if (JWB.isStopped === true) return; if ($('#skipNoChange').prop('checked') && JWB.page.content === newContent) { //skip if no changes are made JWB.log('skip', JWB.page.name); return JWB.next(); } else { JWB.editPage(newContent); } JWB.updateButtons(); }); }); }; //Some functions with self-explanatory names: JWB.api.submit = function(page) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('submit'); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; if ((typeof page === 'string' && page !== JWB.page.name) || $('#currentpage a').html().replace(/&amp;/g, '&') !== JWB.page.name) { console.log(page, JWB.page.name, $('#currentpage a').html()); JWB.stop(); alert(JWB.msg('autosave-error', JWB.msg('tab-log'))); $('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' ')); return; } var newval = $('#editBoxArea').val(); var diffsize = newval.length - JWB.page.content.length; if ($('#sizelimit').val() != 0 && Math.abs(diffsize) > parseInt($('#sizelimit').val())){ alert(JWB.msg('size-limit-exceeded', diffsize > 0 ? '+'+diffsize : diffsize)); JWB.status('done', true); return; } var data = { title: JWB.page.name, summary: summary, action: 'edit', basetimestamp: JWB.page.revisions ? JWB.page.revisions[0].timestamp : '', token: JWB.page.token, text: newval, watchlist: $('#watchPage').val() }; if ($('#minorEdit').prop('checked')) data.minor = true; JWB.api.call(data, function(response) { JWB.log('edit', response.edit.title, response.edit.newrevid); }, function(error, errtype) { var cont = false; if (errtype == 'API') { cont = confirm("API error: " + error.error.info + "\n" + JWB.msg('confirm-continue')); } else { cont = confirm("AJAX error: " + error + "\n" + JWB.msg('confirm-continue')); } if (!cont) { JWB.stop(); } return false; // do not fall back on default error handling }); // While the edit is submitting, continue to the next page to edit. JWB.status('done', true); JWB.next(); }; JWB.api.preview = function(callback) { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('preview'); JWB.api.call({ title: JWB.page.name, action: 'parse', pst: true, text: $('#editBoxArea').val(), prop: 'text|categorieshtml|modules|jsconfigvars', useskin: mw.config.get('skin') }, function(response) { $('#resultWindow').html(response.parse.text['*']); $('#resultWindow div.previewnote').remove(); $('#resultWindow').append(response.parse.categorieshtml['*']); for (var entry of Object.entries(response.parse.jsconfigvars)) { mw.config.set(entry[0], entry[1]); } mw.loader.using(response.parse.modules.concat(response.parse.modulescripts, response.parse.modulestyles), function() { mw.hook('wikipage.content').fire($('#resultWindow .mw-parser-output')); JWB.status('done', true); if (typeof(callback) === 'function') { callback(); } }); }); }; JWB.api.move = function() { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('move'); var topage = $('#moveTo').val().replace(/\$x/gi, JWB.page.pagevar); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var data = { action: 'move', from: JWB.page.name, to: topage, token: JWB.page.token, reason: summary, ignorewarnings: 'yes' }; if ($('#moveTalk').prop('checked')) data.movetalk = true; if ($('#moveSubpage').prop('checked')) data.movesubpages = true; if ($('#suppressRedir').prop('checked')) data.noredirect = true; JWB.api.call(data, function(response) { JWB.log('move', response.move.from, response.move.to); JWB.status('done', true); if (!$('#moveTo').val().match(/\$x/i)) $('#moveTo').val('')[0].focus(); //clear entered move-to pagename if it's not based on the pagevar JWB.next(topage); }); }; JWB.api.del = function() { if (JWB.isStopped) return; // prevent new API calls when stopped var del_action = (!JWB.page.exists ? 'un' : '') + 'delete'; JWB.status(del_action); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var data = { action: del_action, title: JWB.page.name, token: JWB.page.token, reason: summary }; if ($('#deleteTalk').prop('checked')) data[del_action + 'talk'] = true; JWB.api.call(data, function(response) { JWB.log(del_action, (response['delete']||response.undelete).title); JWB.status('done', true); JWB.next(response.undelete && response.undelete.title); }); }; JWB.api.protect = function() { if (JWB.isStopped) return; // prevent new API calls when stopped JWB.status('protect'); var summary = $('#summary').val(); if ($('#summary').parent('label').hasClass('viaJWB')) summary += JWB.summarySuffix; var editprot = $('#editProt').val(); var moveprot = $('#moveProt').val() || editprot; var uploadprot = $('#uploadProt').val() || editprot; var protstring = 'edit='+editprot+'|move='+moveprot; if (!JWB.page.exists) protstring = 'create='+editprot; if (JWB.page.protections.includes('upload')) protstring += '|upload='+uploadprot; JWB.api.call({ action: 'protect', title: JWB.page.name, token: JWB.page.token, reason: summary, expiry: $('#protectExpiry').val()!==''?$('#protectExpiry').val():'infinite', protections: protstring, }, function(response) { var protactions = ''; var prots = response.protect.protections; for (var i=0;i<prots.length;i++) { if (typeof prots[i].edit == 'string') { protactions += ' edit: '+(prots[i].edit || 'all'); } else if (typeof prots[i].move == 'string') { protactions += ' move: '+(prots[i].move || 'all'); } else if (typeof prots[i].create == 'string') { protactions += ' create: '+(prots[i].create || 'all'); } else if (typeof prots[i].upload == 'string') { protactions += ' upload: '+(prots[i].upload || 'all'); } } protactions += ' expires: '+prots[0].expiry; JWB.log('protect', response.protect.title, protactions); JWB.status('done', false); JWB.next(response.protect.title); }); }; JWB.api.watch = function() { JWB.status('watch'); var data = { action: 'watch', title: JWB.page.name, token: JWB.page.watchtoken }; if (JWB.page.watched) data.unwatch = true; JWB.api.call(data, function(response) { JWB.status('<span style="color:green;">'+ JWB.msg('status-watch-'+(JWB.page.watched ? 'removed' : 'added'), "'"+JWB.page.name+"'")+ '</span>', true); JWB.page.watched = !JWB.page.watched; $('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) ); }); }; /***** Pagelist functions *****/ JWB.pl.iterations = 0; JWB.pl.done = true; JWB.pl.stop = function() { if (JWB.pl.done) { JWB.pl.iterations = 0; $('#pagelistPopup [disabled]:not(fieldset [disabled]), #pagelistPopup legend input, #pagelistPopup button').prop('disabled', false); $('#pagelistPopup legend input').trigger('change'); $('#pagelistPopup button img').remove(); } }; JWB.pl.getNSpaces = function() { var list = $('#pagelistPopup [name="namespace"]')[0]; return $('#pagelistPopup [name="namespace"]').val().join('|'); //.val() returns an array of selected options. }; JWB.pl.getList = function(abbrs, lists, data) { $('#pagelistPopup button, #pagelistPopup input, #pagelistPopup select, #pagelistPopup button').prop('disabled', true); JWB.pl.iterations++; if (data.ask !== undefined) { JWB.pl.SMW(data.ask); // execute SMW call in parallel JWB.pl.done = false; data.ask = undefined; } if (!abbrs.length) { JWB.pl.done = true; return; // don't execute the rest; only a SMW query was entered. } data.action = 'query'; var nspaces = JWB.pl.getNSpaces(); for (let i=0;i<abbrs.length;i++) { if (nspaces) data[abbrs[i]+'namespace'] = data[abbrs[i]+'namespace'] || nspaces; // if namespaces are already set, use that instead (for apnamespace) data[abbrs[i]+'limit'] = 'max'; } let linksList = lists.indexOf('links'); if (linksList !== -1) { data.prop = 'links'; lists.splice(linksList, 1); } data.list = lists.join('|'); console.log('generating:', data); JWB.api.call(data, function(response) { var maxiterate = 100; //allow up to 100 consecutive requests at a time to avoid overloading the server. if (!response.query) response.query = {}; if (response.watchlistraw) response.query.watchlistraw = response.watchlistraw; //adding some consistency var plist = []; if (response.query.pages) { var links; for (var id in response.query.pages) { links = response.query.pages[id].links; for (let i=0;i<links.length;i++) { plist.push(links[i].title); } } } for (var l in response.query) { if (l === 'pages') continue; for (let i=0;i<response.query[l].length;i++) { plist.push(response.query[l][i].title); } } //add the result to the pagelist immediately, as opposed to saving it all up and adding in 1 go like AWB does $('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n')); JWB.pageCount(); var cont = response.continue; console.log("Continue",JWB.pl.iterations, cont); if (cont && JWB.pl.iterations <= maxiterate) { var lists = []; if (response.query) { //compatibility with the code I wrote for the old query-continue. TODO: make this unnecessary? for (var list in response.query) { lists.push(list); //add to the new array of &list= values } } var abbrs = []; for (var abbr in cont) { data[abbr] = cont[abbr]; //add the &xxcontinue= value to the data if (abbr != 'continue') { abbrs.push(abbr.replace('continue','')); //find out what xx is and add it to the list of abbrs } } JWB.pl.getList(abbrs, lists, data); //recursive function to get every page of a list } else { if (JWB.pl.iterations > maxiterate) { JWB.status('pl-over-lim', true); } else { JWB.status('done', true); } JWB.pl.stop(); // if JWB.pl.done == true show stopped interface. Otherwise mark as done. JWB.pl.done = true; } }, function() { //on error, simply reset and let the user work with what he has JWB.status('done', true); JWB.pl.stop(); JWB.pl.done = true; }); }; JWB.pl.SMW = function(query) { var data = { action: 'ask', query: query }; JWB.api.call(data, function(response) { console.log(response); let list = response.query.results; let pagevar = response.query.printrequests[1]; let pagevar_type = pagevar && pagevar.typeid; if (pagevar) { // either pagevar === undefined, or it's the first printrequest. pagevar = pagevar.label; } let plist = []; for (let l in list) { let page = list[l]; let name = page.fulltext; let suff; if (pagevar) try { let val = page.printouts[pagevar][0]; if (!val) continue; // this page does not contain this property. switch (pagevar_type) { case '_boo': suff = val == 't'; // true if 't' else false; break; case '_wpg': suff = val.fulltext; break; case '_dat': // val.raw is also available but the unconventional format makes it a lot less convenient. suff = val.timestamp; break; case '_qty': suff = val.value + ' ' + val.unit; break; case '_mlt_rec': // I doubt this is used anywhere, but it's not too hard to support. suff = val.Text.item[0]; break; case '_ref_rec': // not supported; references contain too many properties. break; default: suff = val; } } catch(e) { console.error(e); // show error but ignore. Something is wrong in SMW query/api. } if (suff) { plist.push(name + '|' + suff); } else { plist.push(name); } } $('#articleList').val($.trim($('#articleList').val()) + '\n' + plist.join('\n')); JWB.pageCount(); JWB.pl.stop(); // if JWB.pl.done == true show stopped interface. Otherwise mark as done. JWB.pl.done = true; }); }; //JWB.pl.getList(['wr'], ['watchlistraw'], {}) for watchlists JWB.pl.generate = function() { var $fields = $('#pagelistPopup fieldset').not('[disabled]'); $('#pagelistPopup').find('button[type="submit"]').append('<img src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="15" height="15" alt="'+JWB.msg('status-alt')+'"/>'); var abbrs = [], lists = [], data = {'continue': ''}; $fields.each(function() { var list = $(this).find('legend input').attr('name'); var abbr; if (list === 'linksto') { //Special case since this fieldset features 3 merged lists in 1 fieldset if (!$('[name="title"]').val()) return; $('[name="backlinks"], [name="embeddedin"], [name="imageusage"]').filter(':checked').each(function() { var val = this.value; abbrs.push(val); lists.push(this.name); data[val+'title'] = $('[name="title"]').val(); data[val+'filterredir'] = $('[name="filterredir"]:checked').val(); if ($('[name="redirect"]').prop('checked')) data[val+'redirect'] = true; }); } else if (list === 'smwask') { data.ask = $(this).find('#smwquery').val(); } else { //default input system if ($(this).find('#psstrict').prop('checked')) { // different list if prefixsearch is strict let $input = $(this).find('#psstrict'); list = $input.attr('name'); abbr = $input.val(); } else { abbr = $(this).find('legend input').val(); } lists.push(list); abbrs.push(abbr); $(this).find('input').not('legend input').each(function() { if ((this.type === 'checkbox' || this.type === 'radio') && this.checked === false) return; if (this.id == 'psstrict') return; // ignore psstrict; it only affects how pssearch is handled var name, val; if (this.id == 'cmtitle') { // making sure the page has a Category: prefix, in case the user left it out let cgns = JWB.ns[14]['*']; // name for Category: namespace if (!this.value.startsWith(cgns+':')) { this.value = cgns+':'+this.value; } } if (this.id == 'pssearch' && this.name == 'apprefix') { // apprefix needs namespace separate from pagename name = this.name; let split = this.value.split(':'); val = split[1] || split[0]; let nsid = 0; if (split[1]) { // if a namespace is given for (let ns in JWB.ns) { if (JWB.ns[ns]['*'] == split[0]) { nsid = JWB.ns[ns].id; break; } } } data.apnamespace = nsid; } else { name = this.name; val = this.value; } if (data.hasOwnProperty(name)) { data[name] += '|'+val; } else { data[name] = val; } }); console.log(abbrs, lists, data); } }); if (abbrs.length || data.ask) JWB.pl.getList(abbrs, lists, data); else JWB.pl.stop(); }; /***** Setup functions *****/ JWB.setup.save = function(name) { name = name || prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-store')), $('#loadSettings').val()); if (name === null) return; var self = JWB.settings[name] = { string: {}, bool: {}, replaces: [] }; //inputs with a text value $('textarea, input[type="text"], input[type="number"], select').not('.replaces input, #editBoxArea, #settings *').each(function() { if (typeof $(this).val() == 'string') { self.string[this.id] = this.value.replace(/\n{2,}/g,'\n'); } else { self.string[this.id] = $(this).val(); } }); self.replaces = []; $('.replaces').each(function() { if ($(this).find('.replaceText').val() || $(this).find('.replaceWith').val()) { self.replaces.push({ replaceText: $(this).find('.replaceText').val(), replaceWith: $(this).find('.replaceWith').val(), useRegex: $(this).find('.useRegex').prop('checked'), regexFlags: $(this).find('.regexFlags').val(), ignoreNowiki: $(this).find('.ignoreNowiki').prop('checked') }); } }); $('input[type="radio"], input[type="checkbox"]').not('.replaces input').each(function() { self.bool[this.id] = this.checked; }); if (!$('#loadSettings option[value="'+name+'"]').length) { $('#loadSettings').append('<option value="'+name+'">'+name+'</option>'); } $('#loadSettings').val(name); console.log(self); }; JWB.setup.apply = function(name) { name = name && JWB.settings[name] ? name : 'default'; var self = JWB.settings[name]; $('#loadSettings').val(name); $('.replaces + .replaces').remove(); //reset find&replace inputs $('.replaces input[type="text"]').val(''); $('.useRegex').each(function() {this.checked = false;}); $('#pagelistPopup legend input').trigger('change'); //fix checked state of pagelist generating inputs for (var a in self.string) { $('#'+a).val(self.string[a]); } for (var b in self.bool) { $('#'+b).prop('checked', self.bool[b]); } var cur; for (var c=0;c<self.replaces.length;c++) { if ($('.replaces').length <= c) $('.moreReplaces[data-insert="before"')[0].click(); cur = self.replaces[c]; for (var d in cur) { if (cur[d] === true || cur[d] === false) { $('.replaces').eq(c).find('.'+d).prop('checked', cur[d]); } else { $('.replaces').eq(c).find('.'+d).val(cur[d]); } } } JWB.listReplaces(); $('.useRegex, #containRegex,'+ '#pagelistPopup legend input,'+ '#viaJWB, #enableRETF').trigger('change'); //reset disabled inputs }; JWB.setup.getObj = function() { var settings = []; for (var i in JWB.settings) { if (i != '_blank') { settings.push('"' + i + '": ' + JSON.stringify(JWB.settings[i])); } } return '{\n\t' + settings.join(',\n\t').split('{{subst:').join('{{#JWB-SAFESUBST:#') + '\n}'; }; JWB.setup.submit = function() { var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val()); if (name === null) return; if ($.trim(name) === '') name = 'default'; JWB.setup.save(name); JWB.status('setup-submit'); JWB.api.call({ action: 'query', meta: 'tokens', }, function(response) { let edittoken = response.query.tokens.csrftoken; JWB.api.call({ title: 'User:'+JWB.username+'/'+JWB.settingspage, summary: JWB.msg(['setup-summary', JWB.contentLang]), action: 'edit', token: edittoken, text: JWB.setup.getObj(), minor: true }, function(response) { JWB.status('done', true); JWB.log('edit', response.edit.title, response.edit.newrevid); }); }); }; //TODO: use blob uri JWB.setup.download = function() { var name = prompt(JWB.msg('setup-prompt', JWB.msg('setup-prompt-save')), $('#loadSettings').val()); if (name === null) return; if ($.trim(name) === '') name = 'default'; JWB.setup.save(name); JWB.status('setup-dload'); var url = 'data:application/json;base64,' + btoa(unescape(encodeURIComponent(JWB.setup.getObj()))); var elem = $('#download-anchor')[0]; if (HTMLAnchorElement.prototype.hasOwnProperty('download')) { //use download attribute when possible, for its ability to specify a filename elem.href = url; elem.click(); setTimeout(function() {elem.removeAttribute('href');}, 2000); } else { //fallback to iframes for browsers with no support for download="" attributes elem = $('#download-iframe')[0]; elem.src = url.replace('application/json', 'application/octet-stream'); setTimeout(function() {elem.removeAttribute('src');}, 2000); } JWB.status('done', true); }; JWB.setup.import = function(e) { e.preventDefault(); file = (e.dataTransfer||this).files[0]; if ($(this).is('#import')) { //reset input this.outerHTML = this.outerHTML; $('#import').change(JWB.setup.import); } if (!window.hasOwnProperty('FileReader')) { alert(JWB.msg('old-browser')); JWB.status('old-browser', '<a target="_blank" href="'+JWB.index_php+'?title=Special:MyPage/'+JWB.settingspage+'">/'+JWB.settingspage+'</a>'); return; } if (file.name.split('.').pop().toLowerCase() !== 'json') { alert(JWB.msg('not-json')); return; } JWB.status('Processing file'); var reader = new FileReader(); reader.readAsText(file); reader.onload = function(e) { JWB.status('done', true); try { //Exclusion regex based on http://stackoverflow.com/a/23589204/1256925 //Removes all JS comments from the file, except when they're between quotes. var c = reader.result; var data = JSON.parse(c.replace(/("[^"]*")|(\/\*[\w\W]*\*\/|\/\/[^\n]*)/g, function(match, g1, g2) { if (g1) return g1; })); JWB.setup.extend(data); } catch(e) { alert(JWB.msg('json-err', e.message, JWB.msg('json-err-upload'))); console.log(e); //also log the error for further info return; } }; JWB.status('Processing file'); }; JWB.setup.load = function() { JWB.status('setup-load'); var user = JWB.username||mw.config.get('wgUserName'); var oldtitle = "User:" + user + '/'+JWB.settingspage; // page title for what was used before version 4.0 var newtitle = "User:" + user + '/JWB-settings.json'; // new page title for all settings pages. var titles = oldtitle; // if the old title isn't JWB-settings.json, also query the new title. if (oldtitle !== newtitle && JWB.hasJSON) { titles += '|' + newtitle; } JWB.api.call({ action: 'query', titles: titles, prop: 'info|revisions', meta: 'tokens', rvprop: 'content', indexpageids: true }, function(response) { if (JWB === false) return; //user is not allowed to use JWB var firstrun = !JWB.setup.initialised; JWB.setup.initialised = true; var edittoken = response.query.tokens.csrftoken; // determine correct page to get settings from var pages = response.query.pages, ids = response.query.pageids; var page, exists = true; if (ids.length == 2) { var page0 = pages[ids[0]], page1 = pages[ids[1]]; var oldpage, newpage; if (page0.title == oldtitle) { oldpage = page0; newpage = page1; } else { oldpage = page1; newpage = page0; } if (oldpage.missing === undefined && oldpage.redirect === undefined) { // old page exists and is not a redirect if (newpage.missing === undefined) { // both old AND new page exist; throw error and load neither page. let jsredir = "https://www.mediawiki.org/wiki/Help:Redirects#JavaScript_page_redirect"; prompt(JWB.msg('duplicate-settings', oldtitle, newtitle, jsredir), jsredir); exists = false; } else { // old page exists but new page doesn't; move the page to the new location. JWB.setup.moveNew(oldtitle, newtitle, edittoken); JWB.settingspage = 'JWB-settings.json'; return; } } else { // Old page either doesn't exist or is a redirect. Don't bother with it. page = newpage; exists = (page.missing === undefined); JWB.settingspage = 'JWB-settings.json'; } } else { page = pages[ids[0]]; exists = (page.missing === undefined); } if (!exists) { // settings page does not exist; don't load anything if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded. return; } var data = page.revisions[0]['*'].split('{{#JWB-SAFESUBST:#').join('{{subst:'); if (!data) { // settings page is empty; don't load anything. if (JWB.allowed && firstrun) JWB.setup.save('default'); //this runs when this callback returns after the init has loaded. return; } try { data = JSON.parse(data); } catch(e) { alert(JWB.msg('json-err', e.message, JWB.msg('json-err-page', JWB.settingspage)) || 'JSON error:\n'+e.message); JWB.setup.save('default'); return; } JWB.setup.extend(data); JWB.status('done', true); }); }; JWB.setup.moveNew = function(from, to, token) { var data = { action: 'move', from: from, to: to, token: token, reason: JWB.msg(['setup-move-summary', JWB.contentLang]), noredirect: true, // if possible, suppress redirects; the old page will no longer be needed if the new page exists. movesubpages: true, // if any movetalk: true, // if any ignorewarnings: true, }; if (JWB.hasTag) data.tags = 'JWB'; (new mw.Api()).post(data).done(function(response) { if (response.error === undefined) { JWB.log('move', from, to); JWB.settingspage = to.split('/')[1]; alert(JWB.msg('moved-settings', from, to, JWB.msg('tab-log'))); JWB.setup.load(); // load settings from newly moved page. } }); }; JWB.setup.extend = function(obj) { $.extend(JWB.settings, obj); if (!JWB.settings.hasOwnProperty('default')) { JWB.setup.save('default'); } for (var i in JWB.settings) { if ($('#loadSettings').find('option[value="'+i+'"]').length) continue; $('#loadSettings').append('<option value="'+i+'">'+i+'</option>'); } JWB.setup.apply($('#loadSettings').val()); }; JWB.setup.del = function() { var name = $('#loadSettings').val(); if (name === '_blank') return alert(JWB.msg('setup-delete-blank')); var temp = {}; temp[name] = JWB.settings[name]; JWB.setup.temp = $.extend({}, temp); delete JWB.settings[name]; $('#loadSettings').val('default'); if (name === 'default') { JWB.setup.apply('_blank'); JWB.setup.save('default'); JWB.status(['del-default', '<a href="javascript:JWB.setup.undelete();">'+JWB.msg('status-del-undo')+'</a>'], true); } else { $('#loadSettings').find('[value="'+name+'"]').remove(); JWB.setup.apply(); JWB.status(['del-setup', name, '<a href="javascript:JWB.setup.undelete();">'+JWB.msg('status-del-undo')+'</a>'], true); } }; JWB.setup.undelete = function() { JWB.setup.extend(JWB.setup.temp); JWB.status('done', true); }; /***** Main other functions *****/ //Show status message status-`action`, or status-`action[0]` with arguments `action[1:]` JWB.status = function(action, done) { if (JWB.bot && $('#autosave').prop('checked') && !JWB.isStopped) { $('#summary, .editbutton, #movePage, #deletePage, #protectPage, #skipPage').prop('disabled', true); //Disable summary when auto-saving } else { $('#summary, .editbutton, #movePage, #deletePage, #protectPage, #skipPage').prop('disabled', !done); //Disable box when not done (so busy loading). re-enable when done loading. } var status; if (action instanceof Array) { action[0] = 'status-'+action[0]; status = JWB.msg.apply(this, action); } else { status = JWB.msg('status-'+action); } if (status === false) return; if (status) { if (!done) { //spinner if not done status += ' <img src="//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif" width="15" height="15" alt="'+JWB.msg('status-alt')+'"/>'; } } else { status = action; } $('#status').html(status); JWB.pageCount(); return action=='done'; }; JWB.pageCount = function() { if (JWB.allowed === false||!$('#articleList').length) return; $('#articleList').val(($('#articleList').val()||'').replace(/(^[ \t]*$\n)*/gm, '')); JWB.list = $('#articleList').val().split('\n'); var count = JWB.list.length; if (count === 1 && JWB.list[0] === '') count = 0; $('#totPages').html(count); }; //Generate list of replaces to be performed JWB.listReplaces = function() { JWB.replaces = []; $('.replaces').each(function() { var $this = $(this); var r = []; r[0] = $this.find('.replaceText').val() .replace(/\$x/gi, JWB.page.pagevar) // fill in pagevar .replace(/\\{2}/g, '\\').replace(/\\n/g,'\n'); // handle \n -> newline; r[1] = $this.find('.replaceWith').val(); if (r[0].length == 0 && r[1].length == 0) return; // don't bother replacing 2 empty strings. r[2] = $this.find('.regexFlags').val(); r[3] = $this; JWB.replaces.push(r); }); if (JWB.replaces.length > 1 || ( JWB.replaces.length == 1 && $('.JWBtabc .replaceText').val() == '' && $('.JWBtabc .replaceWith').val() == '' )) { // There are replace rules in the replaces popup $('#replacesButton').addClass('replacesActive'); } else { $('#replacesButton').removeClass('replacesActive'); } }; //Perform all specified find&replace actions JWB.replace = function(input, callback) { JWB.status('replacing'); if (!JWB.worker.isWorking() && JWB.worker.supported) { // if the worker is not already working, then re-init to make sure we've not got any broken leftovers from the previous page JWB.worker.init(); } JWB.newContent = input; JWB.pageCount(); var varOffset = JWB.list[0].indexOf('|') !== -1 ? JWB.list[0].indexOf('|') + 1 : 0; JWB.page.pagevar = JWB.list[0].substr(varOffset); $.each(JWB.replaces, function(i, r) { var replaceText = r[0], replaceWith = r[1], regexFlags = r[2]; var $this = r[3]; var useRegex = replaceText.length == 0 || $this.find('.useRegex').prop('checked'); var replace = replaceText || '$'; // empty string => append (replace /$/ with text) if (useRegex && regexFlags.indexOf('_') !== -1) { replace = replace.replace(/[ _]/g, '[ _]'); //replaces any of [Space OR underscore] with a match for spaces or underscores. replace = replace.replace(/(\[[^\]]*)\[ _\]/g, '$1 _'); //in case a [ _] was placed inside another [] match, remove the []. regexFlags = regexFlags.replace('_', ''); } //apply replaces where \n and \\ work in both regular text and regex mode. var rWith = replaceWith.replace(/\$x/gi, JWB.page.pagevar).replace(/\\{2}/g, '\\').replace(/\\n/g,'\n'); if (rWith.length === 0 && replace === '$') return; try { let replaceDone = function(result, err) { console.log('done replacing', result, err); if (err === undefined) { JWB.newContent = result; if (JWB.worker.queue.length == 0 && JWB.worker.supported) { // all workers are done JWB.status('done', true); callback(JWB.newContent); } } else if (err == 'Timeout exceeded') { if (JWB.worker.queue.length == 0 && JWB.worker.supported) { // all workers have exceeded their time and/or have finished JWB.status('done', true); callback(JWB.newContent); // newContent remains unmodified due to timeout. } } }; if ($this.find('.ignoreNowiki').prop('checked')) { if (!useRegex) { replace = replace.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); regexFlags = 'g'; } JWB.worker.unparsedReplace("~"+"~~JWB.newContent", replace, regexFlags, rWith, replaceDone); } else if (useRegex) { JWB.worker.replace("~"+"~~JWB.newContent", replace, regexFlags, rWith, replaceDone); } else { JWB.newContent = JWB.newContent.split(replace).join(rWith); //global replacement without having to escape all special chars. } } catch(e) { console.log('Regex error:', e); JWB.stop(); return JWB.status('regex-err', false); } }); if ($('#enableRETF').prop('checked')) { JWB.newContent = RETF.replace(JWB.newContent); } if (!JWB.worker.isWorking()) { // no workers were called JWB.status('done', true); callback(JWB.newContent); } }; JWB.skipRETF = function() { if (!$('#enableRETF').prop('checked')) return; // RETF is not enabled to begin with if (JWB.isStopped === true) return; // don't mess with the edit box when stopped $('#enableRETF').prop('checked', false); JWB.replace(JWB.page.content, function(newContent) { JWB.editPage(newContent); JWB.updateButtons(); $('#enableRETF').prop('checked', true); }); }; // Edit the current page and pre-fill the newContent. JWB.editPage = function(newContent) { $('#editBoxArea').val(newContent); $('#currentpage').html(JWB.msg('editbox-currentpage', JWB.page.name, JWB.page.path)); if ($('#preparse').prop('checked')) { $('#articleList').val($.trim($('#articleList').val()) + '\n' + JWB.list[0]); //move current page to the bottom JWB.next(); return; } var onLoadFunctions = { diff: JWB.api.diff, preview: JWB.api.preview }; var autoSaveCallback = JWB.bot && $('#autosave').prop('checked') ? function() { //timeout will take #throttle's value * 1000, if it's a number above 0. Currently defaults to 0. setTimeout(JWB.api.submit, Math.max(+$('#throttle').val() || 0, 0) * 1000, JWB.page.name); } : null; var onLoadFunction = onLoadFunctions[$('#onLoad').val()] || onLoadFunctions.diff; onLoadFunction(autoSaveCallback); }; //Adds a line to the logs tab. JWB.log = function(action, page, info) { var d = new Date(); var pagee = encodeURIComponent(page); var extraInfo = '', actionStat = ''; switch (action) { case 'edit': if (typeof info === 'undefined') { action = 'null-edit'; actionStat = 'nullEdits'; } else { extraInfo = ' (<a target="_blank" href="'+JWB.index_php+'?title='+pagee+'&diff='+info+'">diff</a>)'; actionStat = 'pagesSaved'; } break; case 'nobots': action = 'bot-skip'; extraInfo = ' (<a target="_blank" href="https://trwikiquote.org/wiki/Template:Bots">{{bots}}</a>)'; // no break; case 'skip': actionStat = 'pagesSkipped'; break; case 'move': extraInfo = ' to <a target="_blank" href="/wiki/'+encodeURIComponent(info)+'" title="'+info+'">'+info+'</a>'; break; case 'protect': extraInfo = info; break; } actionStat = '#' + (actionStat || 'otherActions'); $(actionStat).html(+$(actionStat).html() + 1); $('#actionlog tbody') .append('<tr>'+ '<td>'+(JWB.fn.pad0(d.getHours())+':'+JWB.fn.pad0(d.getMinutes())+':'+JWB.fn.pad0(d.getSeconds()))+'</td>'+ '<th>'+action+'</th>'+ '<td><a target="_blank" href="/wiki/'+pagee+'" title="'+page+'">'+page+'</a>'+ extraInfo +'</td>'+ '</tr>') .parents('.JWBtabc').scrollTop($('#actionlog tbody').parents('.JWBtabc')[0].scrollHeight); }; //Move to the next page in the list JWB.next = function(nextPage) { // cancel any still ongoing regex match/replace functions, since we're moving on to another page. JWB.worker.cancelAll(); if ($.trim(nextPage) && !$('#skipAfterAction').prop('checked')) { nextPage = $.trim(nextPage) + '\n'; } else { nextPage = ''; } $('#articleList').val($('#articleList').val().replace(/^.*\n?/, nextPage)); JWB.list.splice(0,1); JWB.pageCount(); JWB.api.get(JWB.list[0].split('|')[0]); }; //Stop everything, reset inputs and editor JWB.stop = function() { console.trace('stopped'); $('#stopbutton,'+ '.editbutton,'+ '#watchNow,'+ '.JWBtabc[data-tab="2"] .editbutton,'+ '#watchNow'+ '.JWBtabc[data-tab="4"] button,'+ '#skipRETF').prop('disabled', true); $('#startbutton, #articleList,'+ '.JWBtabc[data-tab="1"] button,'+ '#replacesPopup button,'+ '#replacesPopup input,'+ '.JWBtabc input, select').prop('disabled', false); $('#resultWindow').html(''); $('#editBoxArea').val(''); $('#currentpage').html(JWB.msg('editbox-currentpage', ' ', ' ')); JWB.pl.done = true; JWB.pl.stop(); JWB.status('done', true); JWB.isStopped = true; }; //Start AutoWikiBrowsing JWB.start = function() { JWB.pageCount(); JWB.listReplaces(); // generate list of replacements to make if (JWB.list.length === 0 || (JWB.list.length === 1 && !JWB.list[0])) { alert(JWB.msg('no-pages-listed')); } else if ($('#skipNoChange').prop('checked') && JWB.replaces.length === 0 && !$('#enableRETF').prop('checked')) { alert(JWB.msg('infinite-skip-notice')); } else { JWB.isStopped = false; if ($('#preparse').prop('checked')) { if (!$('#articleList').val().match('#PRE-PARSE-STOP')) { $('#articleList').val($.trim($('#articleList').val()) + '\n#PRE-PARSE-STOP'); //mark where to stop pre-parsing } } else { $('#preparse-reset').click(); } $('#stopbutton, .editbutton, #watchNow, .JWBtabc[data-tab="2"] button, .JWBtabc[data-tab="4"] button, #skipRETF').prop('disabled', false); $('#startbutton, #articleList, .JWBtabc[data-tab="1"] button, #replacesPopup button, #replacesPopup input, .JWBtabc input, select').prop('disabled', true); if (!JWB.bot || !$('#autosave').prop('checked')) { // keep summary / watchlist options enabled when not in autosave mode $('#minorEdit, #summary, #viaJWB, #watchPage').prop('disabled', false); } JWB.api.get(JWB.list[0].split('|')[0]); } }; JWB.updateButtons = function() { if (!JWB.page.exists && $('#deletePage').is('.delete')) { $('#deletePage').removeClass('delete').addClass('undelete').html(JWB.msg('editbutton-undelete')); JWB.fn.blink('#deletePage'); //Indicate the button has changed } else if (JWB.page.exists && $('#deletePage').is('.undelete')) { $('#deletePage').removeClass('undelete').addClass('delete').html(JWB.msg('editbutton-delete')); JWB.fn.blink('#deletePage'); //Indicate the button has changed } if (!JWB.page.exists) { $('#movePage').prop('disabled', true); } else { $('#movePage').prop('disabled', false); } $('#watchNow').html( JWB.msg('watch-' + (JWB.page.watched ? 'remove' : 'add')) ); }; /***** Web Worker functions *****/ JWB.worker.supported = !!window.Worker; // if window.Worker exists, we can use workers. Unless CSP blocks us. JWB.worker.queue = []; // Load function required to properly load the worker, since directly using `new Worker(url)` for cross-origin URLs does not work even with CORS/CSP rules all allowing it. // See https://stackoverflow.com/q/66188950/1256925 for this exact question JWB.worker.load = function(callback) { if (JWB.worker.blob) return callback(); // already successfully built $.getScript(JWB.imports['worker.js'], function() { // Firefox does not understand try..catch for content security policy violations, so define the worker functions regardless of the blob support. JWB.worker.functions = JWB.worker.function(); // the loaded script just defined JWB.worker.function; convert it to a blob url // Based on https://stackoverflow.com/a/33432215/1256925 if (JWB.worker.supported) try { let blob = new Blob(['('+JWB.worker.function.toString()+')()'], {type: 'text/javascript'}); JWB.worker.blob = URL.createObjectURL(blob); callback(); } catch(e) { if (e.code == 18) { JWB.worker.supported = false; } } }); }; // Create a worker to be able to preform regex operations without hanging the current process. // Based on https://stackoverflow.com/q/66153487/1256925 JWB.worker.init = function() { JWB.worker.load(function() { JWB.worker.worker = new Worker(JWB.worker.blob); JWB.worker.callback = undefined; // explicitly set to the implicit value of undefined. JWB.worker.timeout = 0; JWB.worker.queue = []; JWB.worker.worker.onmessage = function(e) { clearTimeout(JWB.worker.timeout); JWB.worker.timeout = 0; if (JWB.isStopped) { // we're stopped; clear the queue and stop. JWB.worker.queue = []; } else if (JWB.worker.callback !== undefined) { JWB.worker.callback(e.data.result, e.data.err); } else { console.error("Worker finished without callback set:", e.data, e); } JWB.worker.next(true); }; }); }; // Boolean; check if the worker is currently occupied. JWB.worker.isWorking = function() { return JWB.worker.callback !== undefined; }; // Cancel current worker's task (e.g. due to timeout) JWB.worker.terminate = function() { console.log('terminating'); let w = JWB.worker; w.worker.terminate(); w.callback(undefined, 'Timeout exceeded'); let queue = w.queue; // save old queue w.init(); // re-init this worker, since the previous one is presumed dead (and terminated). w.queue = queue; // restore queue }; // Cancel all workers (e.g. due to no longer needing the worker's queued services) JWB.worker.cancelAll = function() { JWB.worker.queue = []; if (JWB.worker.worker) JWB.worker.worker.terminate(); // do not call the callback. }; // Set worker to work, or queue the worker task. JWB.worker.do = function(msg, callback) { if (JWB.worker.isWorking()) { JWB.worker.queue.push({msg: msg, callback: callback}); } else { var timelimit = parseInt($('#timelimit').val()) || 3000; JWB.worker.callback = callback; // Expand "JWB.string" into JWB['string']; to allow the string to be loaded at execution time instead of queue time. // Start with 3x ~ because that cannot exist as the start of an actual page if (msg.str && msg.str.indexOf('~'+'~~JWB.') === 0) msg.str = JWB[msg.str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.worker.postMessage(msg); JWB.worker.timeout = setTimeout(function() { if (!JWB.worker.isWorking()) { console.error('Worker error'); JWB.worker.next(true); return; } JWB.worker.terminate(); JWB.worker.next(true); }, timelimit); } }; // Execute the next task in the queue JWB.worker.next = function(force = false) { if (force) { // force means the function that's calling next() has handled the previous worker task. Clean up after it. JWB.worker.callback = undefined; } else if (JWB.worker.isWorking()) { // still working and the calling function did not specify proper exit of the previous task yet. return false; } if (JWB.worker.queue.length === 0) return true; var q = JWB.worker.queue.shift(); JWB.worker.do(q.msg, q.callback); }; /***** Functions using workers *****/ JWB.worker.match = function(str, pattern, flags, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'match', str, pattern, flags}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.match(str, pattern, flags, callback); } }; JWB.worker.replace = function(str, pattern, flags, rWith, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'replace', str, pattern, flags, rWith}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.replace(str, pattern, flags, rWith, callback); } }; JWB.worker.unparsedReplace = function(str, pattern, flags, rWith, callback) { if (JWB.worker.supported) { JWB.worker.do({cmd: 'unparsedreplace', str, pattern, flags, rWith}, callback); } else { if (str && str.indexOf('~'+'~~JWB.') === 0) str = JWB[str.substr(7)]; // For now, 1-deep expansion is sufficient. JWB.worker.functions.unparsedreplace(str, pattern, flags, rWith, callback); } }; /***** General functions *****/ //Clear all existing timers to prevent them from getting errors JWB.fn.clearAllTimeouts = function() { var i = setTimeout(function() { return void(0); }, 1000); for (var n=0;n<=i;n++) { clearTimeout(n); clearInterval(n); } console.log('Cleared all running intervals up to index',i); }; //Filter an array to only contain unique values. JWB.fn.uniques = function(arr) { var a = []; for (var i=0, l=arr.length; i<l; i++) { if (a.indexOf(arr[i]) === -1 && arr[i] !== '') { a.push(arr[i]); } } return a; }; // code taken directly from [[Template:Bots]] and changed structurally (not functionally) for readability. The user in this case is "JWB" to deny this script. // the user parameter is still kept as an optional parameter to maintain functionality as given on that template page. JWB.fn.allowBots = function(text, user = "JWB") { var usr = user.replace(/([\(\)\*\+\?\.\-\:\!\=\/\^\$])/g, "\\$1"); if (!new RegExp("\\{\\{\\s*(nobots\\s*\\}\\}|bots\\s*(?:\\}\\}|\\|))", "i").test(text)) return true; if (new RegExp("\\{\\{\\s*bots\\s*\\|\\s*deny\\s*=\\s*([^}]*,\\s*)*" + usr + "\\s*(?=[,\\}])[^}]*\\s*\\}\\}", "i").test(text)) return false; else return new RegExp("\\{\\{\\s*((?!nobots)|bots(\\s*\\|\\s*allow\\s*=\\s*((?!none)|([^}]*,\\s*)*" + usr + "\\s*(?=[,\\}])[^}]*|all))?|bots\\s*\\|\\s*deny\\s*=\\s*(?!all)[^}]*|bots\\s*\\|\\s*optout=(?!all)[^}]*)\\s*\\}\\}", "i").test(text); }; //Prepends zeroes until the number has the desired length of len (default 2) JWB.fn.pad0 = function(n, len = 2) { n = n.toString(); return n.length < len ? Array(len-n.length+1).join('0')+n : n; }; JWB.fn.blink = function(el,t) { t=t?t:500; $(el).prop('disabled', true) .children().animate({opacity:'0.1'},t-100) .animate({opacity:'1'},t) .animate({opacity:'0.1'},t-100) .animate({opacity:'1'},t); setTimeout("$('"+el+"').prop('disabled', false)",t*4-400); }; JWB.fn.setSelection = function(el, start, end, dir) { dir = dir||'none'; //Default value end = end||start; //If no end is specified, assume the caret is placed without creating text selection. if (el.setSelectionRange) { el.focus(); el.setSelectionRange(start, end, dir); } else if (el.createTextRange) { var rng = el.createTextRange(); rng.collapse(true); rng.moveStart('character', start); rng.moveEnd('character', end); rng.select(); } }; JWB.fn.scrollSelection = function(el, index) { //function to fix scrolling to selection - doesn't do that automatically. var newEl = document.createElement('textarea'); //create a new textarea to simulate the same conditions var elStyle = getComputedStyle(el); newEl.style.height = elStyle.height; //copy over size-influencing styles newEl.style.width = elStyle.width; newEl.style.lineHeight = elStyle.lineHeight; newEl.style.fontSize = elStyle.fontSize; newEl.value = el.value.substr(0,index); document.body.appendChild(newEl); //needs to be added to the HTML for the scrollHeight and clientHeight to work. if (newEl.scrollHeight != newEl.clientHeight) { el.scrollTop = newEl.scrollHeight - 2; } else { el.scrollTop = 0; } newEl.remove(); //clean up the mess I've made }; //i18n function JWB.msg = function(message) { var args = arguments; var lang = JWB.lang; if (typeof message === 'object') { lang = message[1]; message = message[0]; } if (lang == 'qqx') return message; if (!JWB.messages || !JWB.messages.en) return '\u29FC'+message+'\u29FD'; // same surrounding <> as used in mw.msg(); var msg; if (JWB.messages.hasOwnProperty(lang) && JWB.messages[lang].hasOwnProperty(message)) { msg = JWB.messages[lang][message]; } else { msg = (JWB.messages.en.hasOwnProperty(message)) ? JWB.messages.en[message] : '\u29FC'+message+'\u29FD'; } msg = msg.replace(/\$(\d+)/g, function(match, num) { return args[+num] || match; }); return msg; }; /***** Init *****/ // Check whether or not we are ready to init JWB. If not allowed, abort and delete JWB object to deny access. JWB.checkInit = function() { if (JWB.allowed === false) { var msg = JWB.msg('not-on-list'); JWB = false; delete JWB; alert(msg); return; } JWB.allLoaded = true; for (var m in JWB.messages) if (JWB.messages[m] === null) JWB.allLoaded = false; if (JWB.allowed === true && JWB.allLoaded && Object.keys(JWB.messages).length == JWB.langs.length + 1) { // if there are two languages to load, wait for them both. console.log('langs loaded'); JWB.init(); //init if verification has already returned true } }; // Initialise JWB JWB.init = function() { console.log(JWB.messages.en, !!JWB.messages.en); JWB.setup.load(); JWB.worker.init(); JWB.fn.clearAllTimeouts(); var findreplace = '<div class="replaces">'+ '<label style="display:block;">'+JWB.msg('label-replace')+' <input type="text" class="replaceText"/></label>'+ '<label style="display:block;">'+JWB.msg('label-rwith')+' <input type="text" class="replaceWith"/></label>'+ '<div class="regexswitch">'+ '<label><input type="checkbox" class="useRegex"> '+JWB.msg('label-useregex')+'</label>'+ '<a class="infoLink" href="http://regex101.com/#javascript" target="_blank" tabindex="-1">101</a>'+ '<label class="divisor" title="'+JWB.msg('tip-regex-flags')+'" style="display:none;">'+ JWB.msg('label-regex-flags')+' <input type="text" class="regexFlags" value="g"/>'+ //default: global replacement '</label>'+ '<br/>'+ '</div>'+ '<label title="'+JWB.msg('tip-ignore-comment')+'">'+ '<input type="checkbox" class="ignoreNowiki"> '+JWB.msg('label-ignore-comment')+ '</label>'+ '</div>'; var NSList = '<select multiple name="namespace" id="namespacelist">'; for (var i in JWB.ns) { if (parseInt(i) < 0) continue; //No Special: or Media: in the list NSList += '<option value="'+JWB.ns[i].id+'" selected>'+(JWB.ns[i]['*'] || '('+JWB.msg('namespace-main')+')')+'</option>'; } NSList += '</select>'; /***** Interface *****/ document.title = 'AutoWikiBrowser Script'+(document.title.split('-')[1] ? ' -'+document.title.split('-')[1] : ''); $('body').html( '<article id="resultWindow"></article>'+ '<main id="inputsWindow">'+ '<div id="inputsBox">'+ '<aside id="articleBox">'+ '<b>'+JWB.msg('pagelist-caption')+'</b>'+ '<textarea id="articleList"></textarea>'+ '</aside>'+ '<section id="tabs">'+ '<nav class="tabholder">'+ '<span class="JWBtab active" data-tab="1">'+JWB.msg('tab-setup')+'</span> '+ '<span class="JWBtab" data-tab="2">'+JWB.msg('tab-editing')+'</span> '+ '<span class="JWBtab" data-tab="3">'+JWB.msg('tab-skip')+'</span> '+ (JWB.sysop?'<span class="JWBtab" data-tab="4">'+JWB.msg('tab-other')+'</span> ':'')+ ' <span class="JWBtab log" data-tab="5">'+JWB.msg('tab-log')+'</span> '+ '</nav>'+ '<section class="JWBtabc active" data-tab="1"></section>'+ '<section class="JWBtabc" data-tab="2"></section>'+ '<section class="JWBtabc" data-tab="3"></section>'+ (JWB.sysop?'<section class="JWBtabc" data-tab="4"></section>':'')+ '<section class="JWBtabc log" data-tab="5"></section>'+ '<footer id="status">done</footer>'+ '</section>'+ '<aside id="editBox">'+ '<b>'+JWB.msg('editbox-caption')+' - <span id="currentpage">'+JWB.msg('editbox-currentpage', ' ', ' ')+'</span></b>'+ '<textarea id="editBoxArea" accesskey=","></textarea>'+ '</aside>'+ '</div>'+ '</main>'+ '<footer id="stats">'+ JWB.msg('stat-pages')+' <span id="totPages">0</span>;&emsp;'+ JWB.msg('stat-save')+' <span id="pagesSaved">0</span>;&emsp;'+ JWB.msg('stat-null')+' <span id="nullEdits">0</span>;&emsp;'+ JWB.msg('stat-skip')+' <span id="pagesSkipped">0</span>;&emsp;'+ JWB.msg('stat-other')+' <span id="otherActions">0</span>;&emsp;'+ '</footer>'+ '<div id="overlay" style="display:none;"></div>'+ '<section class="JWBpopup" id="replacesPopup" style="display:none;">'+ '<button class="moreReplaces" data-insert="after">'+JWB.msg('button-more-fields')+'</button>'+ '<br>'+findreplace+ '<button class="moreReplaces" data-insert="before">'+JWB.msg('button-more-fields')+'</button>'+ '</section>'+ '<section class="JWBpopup" id="pagelistPopup" style="display:none;">'+ '<form action="#" id="pl-form"></form>'+ '</section>' ); $('.JWBtabc[data-tab="1"]').html( '<fieldset id="pagelist">'+ '<legend>'+JWB.msg('label-pagelist')+'</legend>'+ '<button id="removeDupes">'+JWB.msg('button-remove-dupes')+'</button> '+ '<button id="sortArticles">'+JWB.msg('button-sort')+'</button>'+ '<br>'+ '<label title="'+JWB.msg('tip-preparse')+'">'+ '<input type="checkbox" id="preparse"> '+JWB.msg('preparse')+ '</label>'+ '<span class="divisor"></span>'+ '<button id="preparse-reset" title="'+JWB.msg('tip-preparse-reset')+'">'+JWB.msg('preparse-reset')+'</button>'+ '<br>'+ '<button id="pagelistButton">'+JWB.msg('pagelist-generate')+'</button>'+ '</fieldset>'+ '<fieldset id="settings">'+ '<legend>'+JWB.msg('label-settings')+'</legend>'+ '<button id="saveAs" title="'+JWB.msg('tip-store-setup')+'">'+JWB.msg('store-setup')+'</button>'+ '<br>'+ '<label>'+ JWB.msg('load-settings') + ' '+ '<select id="loadSettings">'+ '<option value="default" selected>default</option>'+ '<option value="_blank">'+JWB.msg('blank-setup')+'</option>'+ '</select>'+ '</label>'+ '<span class="divisor"></span>'+ '<button id="deleteSetup" title="'+JWB.msg('tip-delete-setup')+'">'+JWB.msg('delete-setup')+'</button>'+ '<hr>'+ '<button id="saveToWiki">'+JWB.msg('save-setup')+'</button>'+ '<span class="divisor"></span>'+ '<button id="download">'+JWB.msg('download-setup')+'</button>'+ '<hr>'+ '<label class="button" id="importLabel" title="'+JWB.msg('tip-import-setup')+'">'+ '<input type="file" id="import" accept=".json">'+ JWB.msg('import-setup')+ '</label>'+ '<span class="divisor"></span>'+ '<button id="updateSetups" title="'+JWB.msg('tip-update-setup', JWB.settingspage)+'">'+JWB.msg('update-setup')+'</button>'+ '<div id="downloads">'+ '<a download="JWB-settings.json" target="_blank" id="download-anchor"></a>'+ '<iframe id="download-iframe"></iframe>'+ '</div>'+ '</fieldset>'+ '<fieldset id="limits">'+ '<legend>'+JWB.msg('label-limits')+'</legend>'+ '<label class="timelimit-label" title="'+JWB.msg('tip-time-limit')+'">'+ JWB.msg('time-limit')+ '<input type="number" id="timelimit" value="3000" min="0">'+ '</label>'+ '<label title="'+JWB.msg('tip-diff-size-limit')+'">'+ JWB.msg('diff-size-limit')+ '<input type="number" id="sizelimit" value="0" min="0">'+ '</label>'+ '</fieldset>' ); $('.JWBtabc[data-tab="2"]').html( '<label class="minorEdit"><input type="checkbox" id="minorEdit" accesskey="i" checked> '+JWB.msg('minor-edit')+'</label>'+ '<label class="editSummary'+(JWB.hasTag?'':' viaJWB')+'">'+JWB.msg('edit-summary')+'<br/> <input class="fullwidth" type="text" id="summary" maxlength="500" accesskey="b"></label>'+ ' <input type="checkbox" id="viaJWB"'+(JWB.hasTag?'':' checked')+' title="'+JWB.msg('tip-via-JWB')+'">'+ '<select id="watchPage">'+ '<option value="watch">'+JWB.msg('watch-watch')+'</option>'+ '<option value="unwatch">'+JWB.msg('watch-unwatch')+'</option>'+ '<option value="nochange" selected>'+JWB.msg('watch-nochange')+'</option>'+ '<option value="preferences">'+JWB.msg('watch-preferences')+'</option>'+ '</select>'+ '<span class="divisor"></span>'+ '<button id="watchNow" disabled accesskey="w">'+ JWB.msg('watch-add')+ '</button>'+ '<br>'+ (JWB.bot? '<label><input type="checkbox" id="autosave"> '+JWB.msg('auto-save')+'</label>'+ '<label title="'+JWB.msg('tip-save-interval')+'" class="divisor">'+ JWB.msg('save-interval', '<input type="number" min="0" value="0" style="width:50px" id="throttle" disabled>')+ '</label>'+ '<br>' :'')+ '<label style="display:block">'+ JWB.msg('on-load')+ ' <select id="onLoad">'+ '<option value="diff" selected>'+JWB.msg('on-load-diff')+'</option>'+ '<option value="preview">'+JWB.msg('on-load-preview')+'</option>'+ '</select>'+ '</label>'+ '<hr>'+ '<span id="startstop">'+ '<button id="startbutton" accesskey="a">'+JWB.msg('editbutton-start')+'</button>'+ '<br>'+ '<button id="stopbutton" disabled accesskey="q">'+JWB.msg('editbutton-stop')+'</button> '+ '</span>'+ '<button class="editbutton" id="skipButton" disabled accesskey="n">'+JWB.msg('editbutton-skip')+'</button>'+ '<button class="editbutton" id="submitButton" disabled accesskey="s">'+JWB.msg('editbutton-save')+'</button>'+ '<br>'+ '<button class="editbutton" id="previewButton" disabled accesskey="p">'+JWB.msg('editbutton-preview')+'</button>'+ '<button class="editbutton" id="diffButton" disabled accesskey="d">'+JWB.msg('editbutton-diff')+'</button>'+ '<button id="replacesButton">'+JWB.msg('button-open-popup')+'</button>'+ findreplace+ '<hr>'+ '<label><input type="checkbox" id="enableRETF"> '+ JWB.msg('label-enable-RETF', '<a href="/wiki/Project:AutoWikiBrowser/Typos" target="_blank">'+ JWB.msg('label-RETF')+ '</a>')+ '</label>'+ ' <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Gnome-view-refresh.svg/20px-Gnome-view-refresh.svg.png"'+ 'id="refreshRETF" title="'+JWB.msg('tip-refresh-RETF')+'">'+ '<br/>'+ '<button id="skipRETF" title="'+JWB.msg('tip-skip-RETF')+'" disabled>'+JWB.msg('skip-RETF')+'</button>' ); $('.JWBtabc[data-tab="3"]').html( '<fieldset>'+ '<legend>'+JWB.msg('label-redirects')+'</legend>'+ '<label title="'+JWB.msg('tip-redirects-follow')+'">'+ '<input type="radio" class="redirects" value="follow" name="redir" id="redir-follow"> '+JWB.msg('redirects-follow')+' '+ '</label>'+ '<label title="'+JWB.msg('tip-redirects-skip')+'">'+ '<input type="radio" class="redirects" value="skip" name="redir" id="redir-skip"> '+JWB.msg('redirects-skip')+' '+ '</label>'+ '<label title="'+JWB.msg('tip-redirects-edit')+'">'+ '<input type="radio" class="redirects" value="edit" name="redir" id="redir-edit" checked> '+JWB.msg('redirects-edit')+''+ '</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('label-skip-when')+'</legend>'+ '<label><input type="checkbox" id="skipNoChange"> '+JWB.msg('skip-no-change')+'</label>'+ '<br>'+ '<label><input type="radio" id="exists-yes" name="exists" value="yes"> '+JWB.msg('skip-exists-yes')+'</label> '+ '<label><input type="radio" id="exists-no" name="exists" value="no" checked> '+JWB.msg('skip-exists-no')+'</label> '+ '<label><input type="radio" id="exists-neither" name="exists" value="neither"> '+JWB.msg('skip-exists-neither')+'</label>'+ (JWB.sysop?'<br><label><input type="checkbox" id="skipAfterAction" checked> '+JWB.msg('skip-after-action')+'</label>':'')+ '<hr/>'+ '<label>'+JWB.msg('skip-contains')+' <input class="fullwidth" type="text" id="skipContains"></label>'+ '<label>'+JWB.msg('skip-not-contains')+' <input class="fullwidth" type="text" id="skipNotContains"></label>'+ '<div class="regexswitch">'+ '<label><input type="checkbox" id="containRegex"> '+JWB.msg('label-useregex')+'</label>'+ '<a class="re101" href="http://regex101.com/#javascript" target="_blank">?</a>'+ '<label class="divisor" title="'+JWB.msg('tip-regex-flags')+'" style="display:none;">'+ JWB.msg('label-regex-flags')+' <input type="text" id="containFlags"/>'+ '</label>'+ '</div>'+ '<hr/>'+ '<label title="'+JWB.msg('skip-cg-prefix')+'">'+JWB.msg('skip-category')+' <input class="fullwidth" type="text" id="skipCategories"></label>'+ '</fieldset>' ); if (JWB.sysop) $('.JWBtabc[data-tab="4"]').html( '<fieldset>'+ '<legend>'+JWB.msg('move-header')+'</legend>'+ '<label><input type="checkbox" id="suppressRedir"> '+JWB.msg('move-redir-suppress')+'</label>'+ '<br>'+ JWB.msg('move-also')+' '+ '<label><input type="checkbox" id="movetalk"> '+JWB.msg('move-talk-page')+'</label> '+ '<label><input type="checkbox" id="movesubpage"> '+JWB.msg('move-subpage')+'</label>'+ '<br>'+ '<label>'+JWB.msg('move-new-name')+' <input type="text" id="moveTo"></label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('delete-header')+'</legend>'+ '<label><input type="checkbox" id="deleteTalk"> '+JWB.msg('delete-talk')+'</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend>'+JWB.msg('protect-header')+'</legend>'+ JWB.msg('protect-edit')+ ' <select id="editProt">'+ '<option value="all" selected>'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ JWB.msg('protect-move')+ ' <select id="moveProt">'+ '<option value="" selected>('+JWB.msg('protect-like-edit')+')</option>'+ '<option value="all">'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ JWB.msg('protect-upload')+ ' <select id="uploadProt">'+ '<option value="" selected>('+JWB.msg('protect-like-edit')+')</option>'+ '<option value="all">'+JWB.msg('protect-none')+'</option>'+ '<option value="autoconfirmed">'+JWB.msg('protect-autoconf')+'</option>'+ '<option value="sysop">'+JWB.msg('protect-sysop')+'</option>'+ '</select> '+ '<br>'+ '<label>'+JWB.msg('protect-expiry')+'<a class="infoLink" href="https://www.mediawiki.org/w/api.php?action=help&modules=main#main/datatypes" target="_blank" tabindex="-1">?</a> <input type="text" id="protectExpiry"/></label>'+ '</fieldset>'+ '<button id="movePage" disabled accesskey="m">'+JWB.msg('editbutton-move')+'</button> '+ '<button id="deletePage" class="delete" disabled accesskey="x">'+JWB.msg('editbutton-delete')+'</button> '+ '<button id="protectPage" disabled accesskey="z">'+JWB.msg('editbutton-protect')+'</button> '+ '<button id="skipPage" disabled title="['+JWB.tooltip+'n]">'+JWB.msg('editbutton-skip')+'</button>'+ '<div class="logActionNote">'+JWB.msg('log-action-note')+'</div>' ); $('.JWBtabc[data-tab="5"]').html('<table id="actionlog"><tbody></tbody></table>'); $('#pagelistPopup form').html( '<div id="ns-filter" title="'+JWB.msg('tip-ns-select')+'">' + JWB.msg('label-ns-select') + NSList + '</div>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="categorymembers" name="categorymembers" value="cm"> '+JWB.msg('legend-cm')+'</label></legend>'+ '<label title="'+JWB.msg('tip-cm')+'">'+JWB.msg('label-cm')+' <input type="text" name="cmtitle" id="cmtitle" class="fullwidth"></label>'+ '<div>'+JWB.msg('cm-include')+' '+ '<label><input type="checkbox" id="cmtype-page" name="cmtype" value="page" checked> '+JWB.msg('cm-include-pages')+'</label>'+ '<label><input type="checkbox" id="cmtype-subcg" name="cmtype" value="subcat" checked> '+JWB.msg('cm-include-subcgs')+'</label>'+ '<label><input type="checkbox" id="cmtype-file" name="cmtype" value="file" checked> '+JWB.msg('cm-include-files')+'</label>'+ '</div>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" name="linksto" id="linksto"> '+JWB.msg('legend-linksto')+'</label></legend>'+ '<label>'+JWB.msg('label-linksto')+' <input type="text" name="title" id="linksto-title" class="fullwidth"></label>'+ '<div>'+JWB.msg('links-include')+' '+ '<label><input type="checkbox" id="backlinks" name="backlinks" value="bl" checked> '+JWB.msg('links-include-links')+'</label>'+ '<label><input type="checkbox" id="embeddedin" name="embeddedin" value="ei"> '+JWB.msg('links-include-templ')+'</label>'+ '<label><input type="checkbox" id="imageusage" name="imageusage" value="iu"> '+JWB.msg('links-include-files')+'</label>'+ '</div>'+ '<div>'+JWB.msg('links-redir')+' '+ '<label><input type="radio" id="rfilter-redir" name="filterredir" value="redirects"> '+JWB.msg('links-redir-redirs')+'</label>'+ '<label><input type="radio" id="rfilter-nonredir" name="filterredir" value="nonredirects"> '+JWB.msg('links-redir-noredirs')+'</label>'+ '<label><input type="radio" id="rfilter-all" name="filterredir" value="all" checked> '+JWB.msg('links-redir-all')+'</label>'+ '</div>'+ '<label title="'+JWB.msg('tip-link-redir')+'">'+ '<input type="checkbox" name="redirect" value="true" checked id="linksto-redir"> '+JWB.msg('label-link-redir')+ '</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="prefixsearch" name="prefixsearch" value="ps"> '+JWB.msg('legend-ps')+'</label></legend>'+ '<label>'+JWB.msg('label-ps')+' <input type="text" name="pssearch" id="pssearch" class="fullwidth"></label>'+ '<label title="'+JWB.msg('tip-ps-strict')+'"><input type="checkbox" name="allpages" value="ap" id="psstrict" checked> '+JWB.msg('label-ps-strict')+'</label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="watchlistraw" name="watchlistraw" value="wr"> '+JWB.msg('legend-wr')+'</label></legend>'+ JWB.msg('label-wr')+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="proplinks" name="links" value="pl"> '+JWB.msg('legend-pl')+'</label></legend>'+ '<label title="'+JWB.msg('tip-pl')+'">'+JWB.msg('label-pl')+' <input type="text" id="titles" name="titles" class="fullwidth"></label>'+ '</fieldset>'+ '<fieldset>'+ '<legend><label><input type="checkbox" id="proplinks" name="search" value="sr"> '+JWB.msg('legend-sr')+'</label></legend>'+ '<label title="'+JWB.msg('tip-sr')+'\n'+JWB.msg('placeholder-sr', 'insource:', 'intitle:')+'">'+ JWB.msg('label-sr')+ ' <input type="text" id="srsearch" name="srsearch" class="fullwidth" placeholder="'+JWB.msg('placeholder-sr', 'insource:', 'intitle:')+'">'+ '</label>'+ '</fieldset>'+ '<fieldset class="listSMW">'+ '<legend><label><input type="checkbox" id="smwask" name="smwask" value="smw"> '+JWB.msg('legend-smw', JWB.msg('smw-slow'))+'</label></legend>'+ '<textarea id="smwquery" name="smwquery" placeholder="'+JWB.msg('label-smw', '\n|limit=500')+'"></textarea>'+ '</fieldset>'+ '<button type="submit">'+JWB.msg('pagelist-generate')+'</button>' ); if (JWB.hasSMW) { $('#pagelistPopup').addClass('hasSMW'); } $('body').addClass('AutoWikiBrowser').addClass('notheme'); //allow easier custom styling of JWB. $('[accesskey]').each(function() { let lbl = this.accessKeyLabel || this.accessKey; // few browsers support accessKeyLabel, so fallback to accessKey. $(this).attr('title', '['+lbl+']'); }); /***** Setup *****/ JWB.setup.save('_blank'); //default setup if (JWB.settings.hasOwnProperty('default')) { JWB.setup.apply(); } else if (JWB.setup.initialised) { // If we already initialised, create the default settings profile. JWB.setup.save('default'); } JWB.setup.extend({}); /***** Event handlers *****/ //Alert user when leaving the tab, to prevent accidental closing. onbeforeunload = function() { return "Closing this tab will cause you to lose all progress."; }; ondragover = function(e) { e.preventDefault(); }; document.addEventListener("securitypolicyviolation", function(e) { console.log('violated CSP:', e); if (e.blockedURI == 'blob') { JWB.worker.supported = false; // tell the next JWB.worker.init() that it shouldn't even try. } else if (JWB && JWB.msg) { alert(JWB.msg('csp-error', e.violatedDirective)); } }); $('.JWBtab').click(function() { $('.active').removeClass('active'); $(this).addClass('active'); $('.JWBtabc[data-tab="'+$(this).attr('data-tab')+'"]').addClass('active'); }); function showRegexFlags() { // >>this<< is the element that's triggered $(this).parent().nextAll('label').toggle(this.checked); } $('body').on('change', '#useRegex, #containRegex, .useRegex', showRegexFlags); $('#preparse-reset').click(function() { $('#articleList').val($('#articleList').val().replace(/#PRE-PARSE-STOP/g,'').replace(/\n\n/g, '\n')); }); $('#saveAs').click(function() { JWB.setup.save(); }); $('#loadSettings').change(function() { JWB.setup.apply(this.value); }); $('#download').click(JWB.setup.download); $('#saveToWiki').click(JWB.setup.submit); $('#import').change(JWB.setup.import); ondrop = JWB.setup.import; $('#updateSetups').click(JWB.setup.load); $('#deleteSetup').click(JWB.setup.del); if (window.RETF) { $('#refreshRETF').click(RETF.load); $('#skipRETF').click(JWB.skipRETF); $('#enableRETF').change(function() { $('#skipRETF').css('visibility', this.checked ? 'visible' : 'hidden'); }); } $('#replacesButton, #pagelistButton').click(function() { var popup = this.id.slice(0, -6); //omits the 'Button' in the id by cutting off the last 6 characters $('#'+popup+'Popup, #overlay').show(); }); $('#overlay').click(function() { $('#replacesPopup, #pagelistPopup, #overlay').hide(); JWB.listReplaces(); JWB.pl.done = true; JWB.pl.stop(); }); $('.moreReplaces').click(function() { var location = $(this).data('insert'); // either call $(this).before() or $(this).after() $(this)[location](findreplace); }); $('#replacesPopup').on('keydown', '.replaces:last', function(e) { if (e.which === 9) $('.moreReplaces[data-insert="before"]')[0].click(); }); $('#pl-form').submit(function(e) { e.preventDefault(); JWB.pl.generate(); return false; }); $('#pagelistPopup legend input').change(function() { //remove disabled attr when checked, add when not. $(this).parents('fieldset').find('input').not('legend input').prop('disabled', !this.checked); $(this).parents('fieldset').prop('disabled', !this.checked); }).trigger('change'); $('#psstrict').change(function() { if (this.checked) { $('#pssearch').attr('name', 'apprefix'); } else { $('#pssearch').attr('name', 'pssearch'); } }).trigger('change'); $('#resultWindow').on('click', 'tr[data-line]:not(.lineheader) *', function(e) { var line = +$(e.target).closest('tr[data-line]').data('line'); var index = $('#editBoxArea').val().split('\n').slice(0, line-1).join('\n').length; $('#editBoxArea')[0].focus(); JWB.fn.setSelection($('#editBoxArea')[0], index+1); JWB.fn.scrollSelection($('#editBoxArea')[0], index); }); $('#removeDupes').click(function() { $('#articleList').val(JWB.fn.uniques($('#articleList').val().split('\n')).join('\n')); JWB.pageCount(); }); $('#sortArticles').click(function() { $('#articleList').val($('#articleList').val().split('\n').sort().join('\n')); JWB.pageCount(); }); $('#watchNow').click(JWB.api.watch); $('#autosave').change(function() { $('#throttle').prop('disabled', !this.checked); }); $('#viaJWB').change(function() { $('#summary').parent('label') .toggleClass('viaJWB', this.checked) .attr('maxlength', 500 - this.checked*JWB.summarySuffix.length); // Change the max size of the allowed summary according to having a suffix or not. }); $('#startbutton').click(JWB.start); $('#stopbutton').click(JWB.stop); $('#submitButton').click(JWB.api.submit); $('#previewButton').click(JWB.api.preview); $('#diffButton').click(JWB.api.diff); $('#skipButton, #skipPage').click(function() { JWB.log('skip', JWB.list[0].split('|')[0]); JWB.next(); }); if (JWB.sysop) { $('#movePage').click(function() { if ($('#moveTo').val().length === 0) { return alert(JWB.msg('alert-no-move')); } JWB.api.move(); }); $('#protectPage').click(JWB.api.protect); $('#deletePage').click(JWB.api.del); } }; //Disable JWB altogether when it's loaded on a page other than Project:AutoWikiBrowser/Script. This script shouldn't be loaded on any other page in the first place. if (JWB.allowed === false) JWB = false; /* JWB sonu */ ryk2olqb5v641a3cmy132lbepxzsrsg 240641 240640 2026-10-16T18:21:20Z Brightt11 34669 --- 240641 javascript text/javascript mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js&action=raw&ctype=text/javascript'); l2wnsqym4alcdkf6n68jtstsww4kk0j Kullanıcı:Brightt11/JWB.js/load.js 2 47574 240637 2026-10-16T18:16:38Z Brightt11 34669 fork from enwiki. en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js/load.js 240637 javascript text/javascript /** This script contains the code required for loading [[User:Joeytje50/JWB.js]]. * All other code is located at that page. */ //Idea by [[User:Epicgenius]] $.when(mw.loader.using(['mediawiki.util'], $.ready)).done( function() { mw.util.addPortletLink("p-tb", mw.config.get('wgArticlePath').replace('$1', "Project:AutoWikiBrowser/Script"), "JS Wiki Browser", "tb-awbscript", "Run Javascript Wiki Browser"); }); if (mw.config.get('wgCanonicalNamespace')+':'+mw.config.get('wgTitle') === 'Project:AutoWikiBrowser/Script' && mw.config.get('wgAction') == 'view') mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Joeytje50/JWB.js&action=raw&ctype=text/javascript'); bxf2lfcs3dud0m96qbw5owjwkummocy