Wîkîferheng kuwiktionary https://ku.wiktionary.org/wiki/Destp%C3%AAk MediaWiki 1.47.0-wmf.10 case-sensitive Medya Taybet Gotûbêj Bikarhêner Gotûbêja bikarhêner Wîkîferheng Gotûbêja Wîkîferhengê Wêne Gotûbêja wêneyî MediaWiki Gotûbêja MediaWiki Şablon Gotûbêja şablonê Alîkarî Gotûbêja alîkariyê Kategorî Gotûbêja kategoriyê Pêvek Gotûbêja pêvekê Nimînok Gotûbêja nimînokê Portal Gotûbêja portalê Tewandin Gotûbêja tewandinê Jinûvesazî Gotûbêja jinûvesaziyê TimedText TimedText talk Modul Gotûbêja modulê Event Event talk aborî 0 5726 6241589 6233303 2026-07-10T21:06:45Z InternetArchiveBot 8979 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 6241589 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === * {{ku-IPA}} * {{deng|ku|LL-Q36163_(kmr)-Key Mîrza-aborî.wav|Deng|Wan}} * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|aborî|mê}} [[Wêne:Billets_de_5000.jpg|thumb|[[pare|Pare]] di aboriyê de giring in.]] {{navdêr|ku|z=m}} # [[karûbar|Karûbar]]ên [[kirîn]] û [[firotin]]ê yên [[tevahî|tevahiya]] [[civak]]ekê. #: {{hevmane|ku|ekonomî|iqtisad}} #: {{mk|ku|'''Aboriya''' wî welatî gelek pêş ketiye.}} # [[hêz|Hêz]]a kesekî ya pê bikare tiştan [[kirîn|bikire]]. #* {{jêder|ku|jêgirtin=Ji ber ko rewşa mala Sîdar ya '''aborî''' ne baş bû; wî him di daîreyeke dewletê de kar dikir û him jî unîversîteya xwe dixwend."|{{Jêgirtin/Bûbê Eser/Gardiyan/2002}}}} # [[bikaranîn|Bikaranîn]]a [[saman]] û [[sermiyan]]î bi awayekî wisa ku zêde xerc nebe lê dîsa jî [[mifa]]yek baş jê bêt wergirtin. #* {{bêmînak|ku}} # [[zanist|Zanist]]a [[aborî|aboriyê]]. #: {{hevmane|ku|aborînasî}} #* {{bêmînak|ku}} ==== Bi alfabeyên din ==== * {{ku-ar|ئابۆری}} * {{ku-kr|абори}} ==== Herwiha ==== * {{g|ku|abûrî}} * {{g|ku|eborî}} * {{g|ku|ebûrî}} ==== Bide ber ==== * {{g|ku|dara}} ==== Jê ==== * {{g|ku|aborînas}} * {{g|ku|aborînasî}} * {{g|ku|aborîvan}} * {{g|ku|aborîvanî}} * {{g|ku|aborîzan}} * {{g|ku|aborîzanî}} ==== Etîmolojî ==== Hevreha soranî {{g|ckb|ئابووری}}, ji {{ji|sem}}, bo nimûne ji {{ji|arc|ku|ܥܒܘܪܐ}} (ibûra / ivûra: [[berhem]], [[ber]], [[dexlûdan]], [[xurak]], [[xwarin]], aborî, [[deramet]]) [https://web.archive.org/web/20210803192702/http://cal.huc.edu/searchroots.php?pos=N&lemma=(br], hevreha akadî [[𒂘]] (ebūru [BURU<sup>14</sup>]: [[xerman]])[http://www.assyrianlanguages.org/akkadian/dosearch.php?searchkey=eb%26%23363%3Bru&language=rawakkadian], {{hv|he|עבור}} (abor: [[ji ber]], [[bermayî]], [[berhem]]), têkilî erebî {{g|ar|عبر}} ('ebere: [[borîn]], [[derbas]] bûn). Ji eynî rehî belkî herwiha: [[borîn]] / [[buhirîn]] û [[borandin]] / [[buhirandin]] yên kurdî. ==== Werger ==== {{werger-ser|iqtisad, birêvebirina serwet û dahatên civakekê}} * {{Z|de}}: {{W+|de|Ökonomie|m}} * {{Z|zgh}}: {{W-|zgh|ⵜⴰⴷⵎⵙⴰ|m}} * {{Z|be}}: {{W-|be|экано́мія|m}} * {{Z|bg}}: {{W+|bg|иконо́мика|m}}, {{W+|bg|стопа́нство|nt}} * {{Z|bua}}: {{W-|bua|ажахы}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|經濟}} * {{Z|da}}: {{W+|da|økonomi|g}}, {{W-|da|husholdning|g}}, {{W-|da|husholdning|g}} * {{Z|ar}}: {{W+|ar|اِقْتِصاد|n}} *: {{Z|acw}}: {{W-|acw|اِقْتِصاد|n|tr=igtiṣād}} * {{Z|eo}}: {{W-|eo|ekonomio}} * {{Z|fi}}: {{W+|fi|talous}} * {{Z|ff}}: *: Adlamî: {{W-|ff|𞤬𞤢𞤺𞥆𞤵𞤣𞤵}} *: Latînî: {{W-|ff|faggudu}} * {{Z|gd}}: {{W-|gd|eaconomaidh|n}} * {{Z|nl}}: {{W+|nl|economie|m}} * {{Z|io}}: {{W+|io|ekonomio}} * {{Z|en}}: {{W+|en|economy}} * {{Z|ga}}: {{W-|ga|barainneacht|m}} * {{Z|it}}: {{W+|it|economia|m}} * {{Z|is}}: {{W-|is|hagur|n}} * {{Z|ja}}: {{W+|ja|経済|tr=けいざい, keizai}} * {{Z|ca}}: {{W+|ca|economia|m}} * {{Z|ko}}: {{W+|ko|경제}} * {{Z|lv}}: {{W+|lv|ekonomika|m}}, {{W+|lv|saimniecība|m}} * {{Z|ms}}: {{W+|ms|ekonomi}} * {{Z|mi}}: {{W-|mi|ōhanga}}, {{W-|mi|taiōhanga}} * {{Z|hu}}: {{W+|hu|gazdaság}} * {{Z|mn}}: *: Kirîlî: {{W-|mn|аж ахуй}} * {{Z|oc}}: {{W+|oc|economia|m}} * {{Z|pl}}: {{W+|pl|gospodarka|m}} * {{Z|pt}}: {{W+|pt|economia|m}} * {{Z|ru}}: {{W+|ru|эконо́мия|m}} * {{Z|scn}}: {{W-|scn|acunumìa|m}}, {{W-|scn|cunumìa|m}}, {{W+|scn|ecunumìa|m}} * {{Z|es}}: {{W+|es|economía|m}} * {{Z|sw}}: {{W+|sw|uchumi}} * {{Z|sv}}: {{W+|sv|ekonomi|g}}, {{W+|sv|hushållning|g}} * {{Z|tl}}: {{W+|tl|ekonomiya}} * {{Z|tr}}: {{W+|tr|ekonomi}}, {{W+|tr|iktisat}}, {{W-|tr|denlik}} * {{Z|ur}}: {{W-|ur|مَعِیشَت|m|tr=ma'išat}} * {{Z|uk}}: {{W+|uk|еконо́мія|m}} * {{Z|el}}: {{W+|el|οικονομία|m}} {{werger-bin}} :{{werger çavkanî|en|economy|beş=Ev qismê Wergerê|oldid=75875500}} === Rengdêr === {{ku-tewîn-rd|aborî}} {{rengdêr|ku}} # [[iqtisadî]], [[ekonomîk]], [[ekonomîkî]], [[têkildarî]] [[aborî#Navdêr|aboriyê]]: #: ''pirsên aborî, mijarên aborî, biryarên aborî'' # [[erzan|Erzan]], ne [[giran]], ne [[bihadar]]. #: ''Min bilêtek '''aborî''' ya trênê kirrî.'' ==== Werger ==== {{werger-ser|iqtisadî, têkildarî aboriyê}} * {{Z|sq}}: {{W+|sq|ekonomik}} * {{Z|de}}: {{W+|de|ökonomisch}}, {{W+|de|Wirtschaft|cuda=Wirtschafts-}} * {{Z|az}}: {{W-|az|iqtisadi}} * {{Z|be}}: {{W-|be|эканамі́чны}}, {{W-|be|гаспада́рскi}} * {{Z|bn}}: {{W-|bn|আর্থিক}} * {{Z|br}}: {{W+|br|armerzhel}} * {{Z|bg}}: {{W+|bg|икономи́чески}}, {{W-|bg|стопа́нски}} * {{Z|my}}: {{W+|my|စီးပွားရေး}} * {{Z|cs}}: {{W+|cs|hospodářský}} * {{Z|zh}}: *: {{Z|cmn}}: {{W+|cmn|經濟|tr=jīngjì}} * {{Z|da}}: {{W-|da|økonomisk}} * {{Z|ar}}: {{W-|ar|اِقْتِصَادِيّ}} * {{Z|hy}}: {{W+|hy|տնտեսական}} * {{Z|eo}}: {{W-|eo|ekonomia}} * {{Z|et}}: {{W-|et|majanduslik}} * {{Z|fa}}: {{W+|fa|اقتصادی|tr=eqtesâdi}} * {{Z|fi}}: {{W+|fi|kansantaloudellinen}} * {{Z|fr}}: {{W+|fr|économique}} * {{Z|gd}}: {{W-|gd|eagonomach}} * {{Z|gl}}: {{W+|gl|económico}} * {{Z|ka}}: {{W-|ka|ეკონომიკური}} * {{Z|hi}}: {{W+|hi|आर्थिक}} * {{Z|nl}}: {{W+|nl|economisch}} * {{Z|he}}: {{W-|he|כַּלְכָּלִי|tr=kalkalí}} * {{Z|en}}: {{W+|en|economic}} * {{Z|ga}}: {{W-|ga|eacnamaíoch}}, {{W-|ga|eacnamúil}} * {{Z|it}}: {{W+|it|economico}} * {{Z|is}}: {{W-|is|hagfræðilegur}} * {{Z|ja}}: {{W+|ja|経済|tr=けいざいの, keizai no|cuda=経済の}}, {{W+|ja|経済的|tr=けいざいてきな, keizaiteki na|cuda=経済的な}} * {{Z|ca}}: {{W+|ca|econòmic}} * {{Z|ky}}: {{W+|ky|экономикалык}} * {{Z|ko}}: {{W+|ko|경제|cuda=경제-의}} * {{Z|lad}}: {{W-|lad|ekonomiko}} * {{Z|lv}}: {{W-|lv|ekonomisks}} * {{Z|lo}}: {{W+|lo|ເສດຖະກິດ}} * {{Z|lt}}: {{W+|lt|ekonominis}} * {{Z|mk}}: {{W-|mk|економски}} * {{Z|ms}}: {{W+|ms|ekonomi}} * {{Z|mt}}: {{W-|mt|ekonomiku}} * {{Z|hu}}: {{W+|hu|gazdasági}} * {{Z|mn}}: *: Kirîlî: {{W-|mn|аж ахуй|cuda=аж ахуйн}} * {{Z|no}}: *: {{Z|nb}}: {{W+|nb|økonomisk}} * {{Z|oc}}: {{W+|oc|economic}} * {{Z|ug}}: {{W-|ug|ئىقتىسادىي}} * {{Z|uz}}: {{W+|uz|iqtisodiy}} * {{Z|ps}}: {{W-|ps|وټه ييز|tr=wëṭa yiz}}, {{W+|ps|اقتصادي|tr=eqtesādi}} * {{Z|pl}}: {{W+|pl|ekonomiczny}}, {{W+|pl|gospodarczy}} * {{Z|pt}}: {{W+|pt|económico}}, {{W+|pt|econômico}} * {{Z|kk}}: {{W-|kk|экономикалық}} * {{Z|ro}}: {{W+|ro|economic}} * {{Z|ru}}: {{W+|ru|экономи́ческий}}, {{W+|ru|хозя́йственный}} * {{Z|sh}}: *: Kirîlî: {{W-|sh|еко̀номскӣ}} *: Latînî: {{W+|sh|ekònomskī}} * {{Z|sk}}: {{W+|sk|hospodársky}} * {{Z|sl}}: {{W-|sl|ekonomski}}, {{W-|sl|gospodarski}} * {{Z|es}}: {{W+|es|económico}} * {{Z|sv}}: {{W+|sv|ekonomisk}} * {{Z|tg}}: {{W-|tg|иқтисодӣ}} * {{Z|tl}}: {{W-|tl|agimatin}} * {{Z|th}}: {{W+|th|เศรษฐกิจ}} * {{Z|tr}}: {{W+|tr|ekonomik}}, {{W+|tr|iktisadi}} * {{Z|tr}}: {{W-|tr|مُعاشی|tr=mu'āśī}}, {{W-|ur|اِقْتِصادی|tr=iqtisādī}} * {{Z|tk}}: {{W-|tk|ykdysady}} * {{Z|uk}}: {{W+|uk|економі́чний}}, {{W-|uk|господа́рський}} * {{Z|vi}}: {{W+|vi|kinh tế}} * {{Z|km}}: {{W+|km|សេដ្ឋកិច្ច}} * {{Z|yi}}: {{W-|yi|עקאָנאָמיש}} * {{Z|el}}: {{W+|el|οικονομικός}} {{werger-bin}} :{{werger çavkanî|en|economic|beş=Ev qismê Wergerê|oldid=75961449}} == {{ziman|zza}} == === Navdêr === {{navdêr|ckb|sc=Latn}} # aborî, [[ekonomî]], [[îqtîsad]]<ref>http://www.kovarabir.com/wp-content/uploads/Ferheng%C3%AA-Dimil%C3%AE-Zazak%C3%AE-%C3%BB-Kurmanc%C3%AE-A-a.pdf</ref>. #* {{bêmînak|zza}} === Çavkanî === {{çavkanî}} 2lztxf295824gvdzhbwd6d32o8dwv8a selef 0 19089 6241552 6098479 2026-07-10T13:37:08Z Zerwanda 12183 /* Etîmolojî */ 6241552 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === <!-- * {{ku-IPA}} --> * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|selef|mê}} {{navdêr|ku|z=m}} # [[faîz]], [[riba]], [[pare]]yê [[zêde]] yê [[divê]] kesa/ê [[deyngir]] bide kesa/ê [[deynder]]<br> (bo nimûne, dema kesek 100 euro bi deyn bide kesekî û 120 euro dîsan lê bên vegerrandin, 20 euroyên zêde faîz e.) #* {{bêmînak|ku}} ==== Herwiha ==== * {{g|ku|fayiz}} * {{g|ku|fayîz}} ==== Jê ==== {{kol3|ku|cure=Jê |selefxwarî<pos:rengdêr> |bêselef |bêselefî |bêselefîtî |bêseleftî |biselef |biselefî |biselefîtî |biseleftî |selefdar |selefdarî |selefdarîtî |selefdartî |selefder |selefderî |selefderîtî |selefdertî |dêr |selefdêr |selefdêrî |selefdêrîtî |selefdêrtî |selefgir |selefgirî |selefgirîtî |selefî |selefstîn |selefstînî |selefstînîtî |selefwergir |selefwergirî |selefwergirîtî }} ==== Etîmolojî ==== Ji {{ji|ar|ku|سلف|ts=sellefe|w=deyn dan}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Vorfahr|m}}, {{W+|de|Zins|m}}, {{W+|de|vergangen}}, {{W+|de|Vorgänger|m|guman=erê}} * {{Z|ar}}: {{W+|ar|ربا|guman=erê}} * {{Z|fa}}: {{W+|fa|بدهی}} * {{Z|fi}}: {{W+|fi|korko}} (lisämaksu) * {{Z|fr}}: {{W+|fr|intérêt|m}} * {{Z|nl}}: {{W+|nl|interest}} * {{Z|en}}: {{W+|en|interest}}, (additional payment) {{W+|en|apple core|guman=erê}} * {{Z|pt}}: {{W+|pt|juros|m}} * {{Z|ro}}: {{W-|ro|dobanda}} * {{Z|tr}}: {{W+|tr|faiz}}, {{W+|tr|getiri}}, {{W+|tr|grup}}, {{W+|tr|kafile}}, {{W-|tr|önceki yıl}}, {{W+|tr|selef}}, {{W+|tr|tefe|guman=erê}}, {{W+|tr|öncel|guman=erê}} {{werger-bin}} == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[pêşrew]], [[pêşawer]], [[selef]] #* {{bêmînak|tr}} iskze14vobkgmichrhme1jnj2hou52g 6241556 6241552 2026-07-10T14:56:04Z Wikihez 7344 /* Navdêr */ [[Bikarhêner:Wikihez/templateScript2.js|TS]]: sererastkirin 6241556 wikitext text/x-wiki == {{ziman|ku}} == === Bilêvkirin === <!-- * {{ku-IPA}} --> * {{ku-kîte}} === Navdêr === {{ku-tewîn-nav|selef|mê}} {{navdêr|ku|z=m}} # [[pare|Pare]]yê [[zêde]] yê [[divê]] kesa/ê [[deyngir]] bide kesa/ê [[deynder]]<br> (bo nimûne, dema kesek 100 euro bi deyn bide kesekî û 120 euro dîsan lê bên vegerrandin, 20 euroyên zêde faîz e.) #: {{hevmane|ku|faîz|riba}} #* {{bêmînak|ku}} ==== Herwiha ==== * {{g|ku|fayiz}} * {{g|ku|fayîz}} ==== Jê ==== {{kol3|ku|cure=Jê |selefxwarî<pos:rengdêr> |bêselef |bêselefî |bêselefîtî |bêseleftî |biselef |biselefî |biselefîtî |biseleftî |selefdar |selefdarî |selefdarîtî |selefdartî |selefder |selefderî |selefderîtî |selefdertî |dêr |selefdêr |selefdêrî |selefdêrîtî |selefdêrtî |selefgir |selefgirî |selefgirîtî |selefî |selefstîn |selefstînî |selefstînîtî |selefwergir |selefwergirî |selefwergirîtî }} ==== Etîmolojî ==== Ji {{ji|ar|ku|سلف|ts=sellefe|w=deyn dan}}. ==== Werger ==== {{werger-ser}} * {{Z|de}}: {{W+|de|Vorfahr|m}}, {{W+|de|Zins|m}}, {{W+|de|vergangen}}, {{W+|de|Vorgänger|m|guman=erê}} * {{Z|ar}}: {{W+|ar|ربا|guman=erê}} * {{Z|fa}}: {{W+|fa|بدهی}} * {{Z|fi}}: {{W+|fi|korko}} (lisämaksu) * {{Z|fr}}: {{W+|fr|intérêt|m}} * {{Z|nl}}: {{W+|nl|interest}} * {{Z|en}}: {{W+|en|interest}}, (additional payment) {{W+|en|apple core|guman=erê}} * {{Z|pt}}: {{W+|pt|juros|m}} * {{Z|ro}}: {{W-|ro|dobanda}} * {{Z|tr}}: {{W+|tr|faiz}}, {{W+|tr|getiri}}, {{W+|tr|grup}}, {{W+|tr|kafile}}, {{W-|tr|önceki yıl}}, {{W+|tr|selef}}, {{W+|tr|tefe|guman=erê}}, {{W+|tr|öncel|guman=erê}} {{werger-bin}} == {{ziman|tr}} == === Rengdêr === {{rengdêr|tr}} # [[pêşrew]], [[pêşawer]], [[selef]] #* {{bêmînak|tr}} 91kf0yc6p3jci8ptkrt5esvka13ej89 Artikel 0 115907 6241579 6065047 2026-07-10T20:22:10Z Wikihez 7344 /* */ bi [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]ê re 6241579 wikitext text/x-wiki {{bnr-h|artîkel}} == {{ziman|de}} == === Bilêvkirin === * {{IPA|de|[aʁˈtiːkl̩]}} * {{deng|de|De-Artikel2.ogg|Deng|dever=Berlîn, Almanya}} * {{deng|de|LL-Q188 (deu)-Sebastian Wallroth-Artikel.wav|Deng|dever=Berlîn, Almanya}} * {{deng|de|De-Artikel.ogg|Deng}} * {{kîte|de|Ar|ti|kel}} === Navdêr === {{navdêr|de|z=n}} # [[gotar]], [[nivîsar]] ay9s2u944mah7f7qk3nxrzu4tx1s6uu Bikarhêner:Wikihez/test.js 2 969083 6241544 6241543 2026-07-10T13:10:58Z Wikihez 7344 6241544 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form input[type='text']," + "#wiktvi-start-form textarea {" + " resize: both;" + " overflow: auto;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $(mw.html.element("input", { type: "text", "class": currentInput.attr("class") })); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $(mw.html.element("input", { type: "text", "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> do8vg0nclqlm37uupbkju730ljf8pf0 6241545 6241544 2026-07-10T13:15:37Z Wikihez 7344 6241545 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form input[type='text']," + "#wiktvi-start-form textarea {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $(mw.html.element("input", { type: "text", "class": currentInput.attr("class") })); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $(mw.html.element("input", { type: "text", "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> eywplvrhj1ez155ibz4fo74086ft7cc 6241546 6241545 2026-07-10T13:20:35Z Wikihez 7344 6241546 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box;" + " vertical-align: top;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", "1"); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", "1"); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> kjwx176uku700ti1kqrof4xwzc3x70b 6241547 6241546 2026-07-10T13:24:23Z Wikihez 7344 6241547 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box;" + " vertical-align: top;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 18cu6mhchig8czcynsc5v31ihoi6ugn 6241548 6241547 2026-07-10T13:27:16Z Wikihez 7344 6241548 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " height: 1.8em !important;" + " min-height: 1.8em !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> trsvmdr4fw1tkfmqh758iniqythrxp2 6241549 6241548 2026-07-10T13:28:43Z Wikihez 7344 ([[m:Special:MyLanguage/User:Jon Harald Søby/diffedit|diffedit]]) 6241549 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " height: 0.5em !important;" + " min-height: 0.5em !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> ozogzigv0vrcg3lf3cb00tqjteoxtx2 6241550 6241549 2026-07-10T13:30:02Z Wikihez 7344 6241550 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " height: calc(1em + 8px) !important;" + " min-height: calc(1em + 8px) !important;" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> f8jchelkcj7r68zvs3is1frd55wul4b 6241551 6241550 2026-07-10T13:32:03Z Wikihez 7344 6241551 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " width: 20em !important;" + " height: calc(1em + 8px) !important;" + " min-height: calc(1em + 8px) !important;" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Maneya peyvê di nivîsa sade de bi kurmancî binivîse. Ji bo tercimeyan beşa Wergerê bi kar bîne.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos; return values.lang === "ku" ? examples[pos] : transExamples[pos]; }, getOutput: function (values, callback) { var text = $.map(values.dfn, function (dfn, i) { dfn = $.trim(dfn); if (!dfn) return undefined; // Capitalize the first word. if (dfn[0] !== dfn[0].toUpperCase()) { dfn = capitalize(dfn); } // Punctuate the definition. if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // Generate the output for dfn var output = "# " + dfn; // Get the corresponding nimunes for the current dfn var nimunes = i === 0 && values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); output += formatNimune(nimunes, values.lang); return output; }).join("\n") + "\n\n"; // Check if dfn is not empty before calling $.wiktviLinkify if ($.trim(values.dfn.join("")) !== "") { var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } else { // Get the corresponding nimunes for the current dfn var nimunes = values.nimune ? values.nimune : []; // Trim each nimune nimunes = nimunes.map(function(nimune) { return $.trim(nimune); }); // Use the default value if dfn is empty text = "# {{mane?|" + values.lang + "}}" + formatNimune(nimunes, values.lang) + "\n\n"; callback(text); } } }, nimune: { id: "nimune", name: "nimûne", question_fmt: "Nimûneyên bikaranîna peyvê binivîse (hemû ji bo maneya yekê)", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; } }, variant: makeWordListStep("variant", "herwiha", "Guhartoyên peyvê binivîse", "Herwiha", "g"), syn: makeWordListStep("syn", "hevmane", undefined, "Hevmane", "g"), ant: makeWordListStep("ant", "dijmane", undefined, "Dijmane", "g"), je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.nimune, steps.variant, steps.syn, steps.ant, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.variant.output(values); entry += steps.syn.output(values); entry += steps.ant.output(values); entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + values.dfn.join("; "); document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> ldeyyp1mbjr7p9e5lnrsbbmx54icxza 6241553 6241551 2026-07-10T13:42:53Z Wikihez 7344 6241553 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " width: 20em !important;" + " height: calc(1em + 8px) !important;" + " min-height: calc(1em + 8px) !important;" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); // Return null — prepareInput is a no-op for custom steps // that manage their own change events. return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> qntlwskg6lgbic3iwytnhc0aepsy1t2 6241554 6241553 2026-07-10T13:52:03Z Wikihez 7344 6241554 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow {" + " width: 20em !important;" + " height: calc(1em + 8px) !important;" + " min-height: calc(1em + 8px) !important;" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> tkuqt1ps2chmibktffrq4tzvl5o8qyp 6241555 6241554 2026-07-10T14:23:25Z Wikihez 7344 6241555 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", multiple: true, narrow: true, rows: 2, keyName: "ziman", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, example: function (values) { var examples = 'Di navbera peyvan de bêhnok "," bi kar bîne.'; return examples; }, output: function (values) { var rows = []; $.each(values.trans, function (lang, words) { if (words) rows.push([lang, words]); }); var outputString; if (values.lang === "ku") { outputString = "\n\n==== Werger ====\n{{werger-ser}}"; // Check if there are translations if (rows.length) { outputString += "\n"; // Sort the rows rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); // Add the translations outputString += $.map(rows, function (row, i) { var words = escapeTemplateParam(row[1]).replace(/(\s*[,;()]+\s*)/g, "}}$1{{W|" + row[0] + "|"); return "* {{Z|" + row[0] + "}}: {{W|" + row[0] + "|" + words + "}}"; }).join("\n"); } // Add the closing section header outputString += "\n{{werger-bin}}\n\n"; }else { outputString = ""; } return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> s1qtfxc59i2ivj0ko8wb3josrzz78kd 6241557 6241555 2026-07-10T17:18:04Z Wikihez 7344 6241557 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector (reuse chosen options). var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); langSel.chosen(chosenOptions); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { list.append(steps.trans.buildRow(stepDiv)); // Update chosen on the new row's select after it's in DOM. list.children("li.wiktvi-trans-row:last-child") .find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(" "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> dsi2txiha3y4c1ggut211qcp0w246c0 6241558 6241557 2026-07-10T17:21:08Z Wikihez 7344 6241558 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM. newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen now that the select is in the DOM. list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(" "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> niakeryw156tzgsh0ft7cxjni73mwxb 6241559 6241558 2026-07-10T17:28:05Z Wikihez 7344 6241559 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); row.append(langSel).append(wordList); return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM. newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen now that the select is in the DOM. list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); stepDiv.append(input); } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> cfchrq1zkrvv6a2nz1r7zthxb6deazw 6241560 6241559 2026-07-10T17:33:24Z Wikihez 7344 6241560 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " margin-bottom: 4px;" + " box-sizing: border-box;" + "}" + ".wiktvi-native-select-wrap select {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, chosen is replaced with a native <select> preceded by a * live-filter <input>. The filter hides non-matching <option> elements * by rebuilding the option list on each keystroke. * * The returned object mimics the jQuery chosen API surface used elsewhere: * .chosen(opts) — no-op (already initialised) * .trigger("chosen:updated") — repopulates the native select * .val() — native select .val() * .on("change", fn) — native select change event */ function wrapNativeSelect(select) { // Build a small filter input above the select. var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var filterInput = $("<input type='search'>") .attr("placeholder", select.attr("data-placeholder") || "Lêbigere…") .addClass("wiktvi-start-narrow"); // Store the full option list so we can re-filter without losing entries. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { allOptions.push({ value: $(this).val(), text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function applyFilter(query) { var q = query.trim().toLowerCase(); var currentVal = select.val(); select.empty(); $.each(allOptions, function (_, opt) { if (!q || opt.text.toLowerCase().indexOf(q) !== -1) { var el = $("<option></option>").val(opt.value).text(opt.text); if (opt.disabled) el.prop("disabled", true); select.append(el); } }); // Restore selection if it's still visible. if (currentVal) select.val(currentVal); } filterInput.on("input", function () { applyFilter($(this).val()); }); // chosen:updated → re-cache options (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); applyFilter(filterInput.val()); }); // Expose a no-op .chosen() so call sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(filterInput).append($("<br>")).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> qiktni171nx5m0bjevxtzckdypm6v42 6241561 6241560 2026-07-10T17:40:01Z Wikihez 7344 6241561 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " margin-bottom: 4px;" + " box-sizing: border-box;" + "}" + ".wiktvi-native-select-wrap select {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, chosen is replaced with a native <select> preceded by a * live-filter <input>. The filter hides non-matching <option> elements * by rebuilding the option list on each keystroke. * * The returned object mimics the jQuery chosen API surface used elsewhere: * .chosen(opts) — no-op (already initialised) * .trigger("chosen:updated") — repopulates the native select * .val() — native select .val() * .on("change", fn) — native select change event */ function wrapNativeSelect(select) { // Build a small filter input above the select. var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var filterInput = $("<input type='search'>") .attr("placeholder", select.attr("data-placeholder") || "Lêbigere…") .addClass("wiktvi-start-narrow"); // Store the full option list so we can re-filter without losing entries. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { allOptions.push({ value: $(this).val(), text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function applyFilter(query) { var q = query.trim().toLowerCase(); var currentVal = select.val(); select.empty(); $.each(allOptions, function (_, opt) { if (!q || opt.text.toLowerCase().indexOf(q) !== -1) { var el = $("<option></option>").val(opt.value).text(opt.text); if (opt.disabled) el.prop("disabled", true); select.append(el); } }); // Restore selection if it's still visible. if (currentVal) select.val(currentVal); // If filtering left exactly one selectable option, auto-select it // and fire change so downstream steps (refresh) react immediately. var selectableOpts = select.find("option:not([disabled])").filter(function () { return $(this).val() !== ""; }); if (selectableOpts.length === 1) { var autoVal = selectableOpts.first().val(); if (autoVal !== currentVal) { select.val(autoVal); select.trigger("change"); } } } filterInput.on("input", function () { applyFilter($(this).val()); }); // chosen:updated → re-cache options (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); applyFilter(filterInput.val()); }); // Expose a no-op .chosen() so call sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(filterInput).append($("<br>")).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 3as63zmcyut442hrov3w8txwtz9s78n 6241562 6241561 2026-07-10T17:43:50Z Wikihez 7344 6241562 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr"], ["navdêr/m", "Navdêra mê"], ["navdêr/n", "Navdêra nêr"], ["navdêr/mn", "Navdêra mê û nêr"], ["navdêr/nt", "Navdêra nêtar"], ["lêker", "Lêker"], ["lêker/gh", "Lêkera gerguhêz"], ["lêker/ngh", "Lêkera negerguhêz"], ["lêker/x", "Lêkera xwerû"], ["lêker/x-gh", "Lêkera xwerû û gerguhêz"], ["lêker/x-ngh", "Lêkera xwerû û nergerguhêz"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/p-gh", "Lêkera pêkhatî û gerguhêz"], ["lêker/p-ngh", "Lêkera pêkhatî û negerguhêz"], ["lêker/b", "Lêkera biwêjî"], ["lêker/b-gh", "Lêkera biwêjî û gerguhêz"], ["lêker/b-ngh", "Lêkera biwêjî û negerguhêz"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["serenav/m", "Serenava mê"], ["serenav/n", "Serenava nêr"], ["serenav/mn", "Serenava mê û nêr"], ["serenav/nt", "Serenava nêtar"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan", "Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { // Split values.pos based on hyphen var posParts = values.pos.split("/"); // Extract the part without gender var posWithoutGender = posParts[0]; // Extract the gender part var gender = posParts.length > 1 ? posParts[1] : ""; // Capitalize the first letter of the extracted part var capitalizedPos = capitalize(posWithoutGender); var outputString = "=== " + capitalizedPos + " ===\n"; const genders = { 'm': 'mê', 'n': 'nêr', 'mn': 'mê û nêr', }; // Check the conditions for adding "{{ku-tewîn-nav}}" if (!pageName.includes(" ") && gender && genders[gender] && (posWithoutGender === "navdêr" || posWithoutGender === "serenav") && values.lang === "ku") { const genderName = genders[gender]; outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderName + "}}\n"; } outputString += "{{" + posWithoutGender + "|" + values.lang; // Not: "nt" (nêtar) êdî nayê veguherandin bo "mn" li vir. // Ne di tabloya "genders" de ("nt" hîna jî tabloya kişandinê // nagire), ne jî li vir — "nt" ceribandî wek "nt" derdikeve // di |z=-ê de, li şûna ku bibe "mê û nêr". if (gender) { if (posWithoutGender === "navdêr" || posWithoutGender === "serenav") { outputString += "|z=" + gender; }else if (posWithoutGender === "lêker") { outputString += "|c=" + gender; } } // Check the conditions for adding "|z=?" if ((values.pos === "navdêr" || values.pos === "serenav") && values.lang === "ku") { outputString += "|z=?"; } // Add values from values.tr to the output string if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } // Complete the output string outputString += "}}\n"; return outputString; } }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); startForm.append(footer); $("#editform").hide().before(startForm); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 6e3bmg5yumbeptk08z6m576wdotf7av 6241563 6241562 2026-07-10T18:06:57Z Wikihez 7344 6241563 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); startForm.after(previewPanel); $("#editform").hide().before(startForm); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> t4wzzsj6w4drytt3tjto3kpb6p1ng4q 6241564 6241563 2026-07-10T18:10:55Z Wikihez 7344 6241564 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> m6uoa481aljiujr9bhjt796qvm1hgvg 6241565 6241564 2026-07-10T18:32:04Z Wikihez 7344 6241565 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Hardcoded fallback list for tr= step — overridden by LangMetadata if loaded. var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; // LangMetadata instance — populated asynchronously after the data script loads. // Use langMeta.getGenders(code) and langMeta.guessScript(code) once available. var langMeta = null; // Maps TranslationAdder-Data gender codes → Kurmancî display labels for zayend. // Extend this dict to support more gender values shown in the data script. var genderLabels = { "m": "Mê", "n": "Nêr", "mn": "Mê û nêr", "nt": "Nêtar", "m-p": "Mê (pirjimar)", "n-p": "Nêr (pirjimar)", "nt-p": "Nêtar (pirjimar)", "g": "Giştî", "g-p": "Giştî (pirjimar)", "y": "Yekjimar", "p": "Pirjimar" }; // Latin-based script codes — languages using these do NOT need tr= transcription. var latinScripts = { Latn: 1, Hebr: 1 }; // Returns true when a language needs manual transcription input. function needsTr(langCode) { if (langMeta) { var sc = langMeta.guessScript(langCode); // If script is unknown or Latin/Hebrew, no tr= needed. if (!sc) return false; return !latinScripts[sc]; } // Fallback before LangMetadata loads. return trRequired.indexOf(langCode) !== -1; } // Returns the zayend choices for the currently selected language. // Uses LangMetadata if loaded, falls back to the static list. function getZayendChoices(langCode) { if (langMeta) { var gs = langMeta.getGenders(langCode); if (gs && gs.length) { // Filter to single-word (non-plural) gender codes only — plural // genders are not relevant to the zayend step. return gs .filter(function (g) { return genderLabels[g]; }) .map(function (g) { return [g, genderLabels[g]]; }); } return []; // language has no genders } // Fallback: static list used before LangMetadata loads. return [["m","Mê"],["n","Nêr"],["mn","Mê û nêr"],["nt","Nêtar"]]; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { if (!(values.lang && (values.pos === "navdêr" || values.pos === "serenav"))) return false; // Hide if LangMetadata says this language has no genders. return getZayendChoices(values.lang).length > 0; }, // choices is populated dynamically via build() using getZayendChoices(). choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], build: function (stepDiv, values) { if (!values || !values.lang) return null; var choices = getZayendChoices(values.lang); var sel = stepDiv.find("#wiktvi-start-zayend-field"); if (!sel.length) { // First build — create the select. sel = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-zayend-field" })); sel.attr("data-placeholder", "Zayend hilbijêre"); if (isMobile) { stepDiv.append(wrapNativeSelect(sel)); } else { stepDiv.append(sel); } } // Repopulate options every time (lang may have changed). populateMenus(sel, choices); if (!isMobile) sel.trigger("chosen:updated"); return isMobile ? null : sel; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTr(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } // Load TranslationAdder-Data.js for dynamic gender and script metadata. // Works whether the script is loaded as a personal script or a gadget. // Once loaded, LangMetadata becomes available on window; instantiate it // and trigger a refresh so zayend/tr steps update immediately. function loadLangMetadata() { if (window.LangMetadata) { langMeta = new window.LangMetadata(); refresh(); return; } // Try gadget first; fall back to user script URL. var gadgetModule = "ext.gadget.TranslationAdder-Data"; var userScriptUrl = "https://ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript"; mw.loader.using(gadgetModule).then(function () { if (window.LangMetadata) { langMeta = new window.LangMetadata(); refresh(); } }, function () { // Gadget not found — load from user script URL. mw.loader.load(userScriptUrl); mw.loader.using("mediawiki.api").then(function () { // Poll briefly until LangMetadata appears (script is async). var tries = 0; var poll = setInterval(function () { if (window.LangMetadata || ++tries > 20) { clearInterval(poll); if (window.LangMetadata) { langMeta = new window.LangMetadata(); refresh(); } } }, 200); }); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], function () { build(); loadLangMetadata(); }); }); //</nowiki> 38pg0ldk2t1052bln0eabckvdka69o4 6241566 6241565 2026-07-10T18:34:13Z Wikihez 7344 6241566 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Hardcoded fallback list for tr= step — overridden by LangMetadata if loaded. var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; // LangMetadata instance — populated asynchronously after the data script loads. // Use langMeta.getGenders(code) and langMeta.guessScript(code) once available. var langMeta = null; // Maps TranslationAdder-Data gender codes → Kurmancî display labels for zayend. // Extend this dict to support more gender values shown in the data script. var genderLabels = { "m": "Mê", "n": "Nêr", "mn": "Mê û nêr", "nt": "Nêtar", "m-p": "Mê (pirjimar)", "n-p": "Nêr (pirjimar)", "nt-p": "Nêtar (pirjimar)", "g": "Giştî", "g-p": "Giştî (pirjimar)", "y": "Yekjimar", "p": "Pirjimar" }; // Latin-based script codes — languages using these do NOT need tr= transcription. var latinScripts = { Latn: 1, Hebr: 1 }; // Returns true when a language needs manual transcription input. function needsTr(langCode) { if (langMeta) { var sc = langMeta.guessScript(langCode); // If script is unknown or Latin/Hebrew, no tr= needed. if (!sc) return false; return !latinScripts[sc]; } // Fallback before LangMetadata loads. return trRequired.indexOf(langCode) !== -1; } // Returns the zayend choices for the currently selected language. // Uses LangMetadata if loaded, falls back to the static list. function getZayendChoices(langCode) { if (langMeta) { var gs = langMeta.getGenders(langCode); if (gs && gs.length) { // Filter to single-word (non-plural) gender codes only — plural // genders are not relevant to the zayend step. return gs .filter(function (g) { return genderLabels[g]; }) .map(function (g) { return [g, genderLabels[g]]; }); } return []; // language has no genders } // Fallback: static list used before LangMetadata loads. return [["m","Mê"],["n","Nêr"],["mn","Mê û nêr"],["nt","Nêtar"]]; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { if (!(values.lang && (values.pos === "navdêr" || values.pos === "serenav"))) return false; // Hide if LangMetadata says this language has no genders. return getZayendChoices(values.lang).length > 0; }, // choices is populated dynamically via build() using getZayendChoices(). choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], build: function (stepDiv, values) { if (!values || !values.lang) return null; var choices = getZayendChoices(values.lang); var sel = stepDiv.find("#wiktvi-start-zayend-field"); if (!sel.length) { // First build — create the select. sel = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-zayend-field" })); sel.attr("data-placeholder", "Zayend hilbijêre"); if (isMobile) { stepDiv.append(wrapNativeSelect(sel)); } else { stepDiv.append(sel); } } // Repopulate options every time (lang may have changed). populateMenus(sel, choices); if (!isMobile) sel.trigger("chosen:updated"); return isMobile ? null : sel; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTr(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } // Load TranslationAdder-Data.js for dynamic gender and script metadata. // Works whether the script is loaded as a personal script or a gadget. // Once loaded, LangMetadata becomes available on window; instantiate it // and trigger a refresh so zayend/tr steps update immediately. function loadLangMetadata() { if (window.LangMetadata) { // Already available (e.g. loaded by another gadget earlier in the session). try { langMeta = new window.LangMetadata(); refresh(); } catch (e) {} return; } var gadgetModule = "ext.gadget.TranslationAdder-Data"; var langUtilsModule = "ext.gadget.LanguageUtils"; var userScriptUrl = "https://ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript"; function tryInstantiate() { if (!window.LangMetadata) return; try { langMeta = new window.LangMetadata(); refresh(); } catch (e) {} } // LanguageUtils must be loaded first — LangMetadata's constructor calls // new ScriptUtils() which lives in that module. mw.loader.using(langUtilsModule).then(function () { // Now try loading the data script as a gadget. mw.loader.using(gadgetModule).then( function () { tryInstantiate(); }, function () { // Gadget not registered — fall back to user script URL. $.getScript(userScriptUrl).done(tryInstantiate); } ); }, function () { // LanguageUtils gadget not found either — just try the data script // directly and hope ScriptUtils is a no-op or already present. $.getScript(userScriptUrl).done(tryInstantiate); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], function () { build(); loadLangMetadata(); }); }); //</nowiki> 1a66shckb5bfutd86vmn2isbfpag60f 6241567 6241566 2026-07-10T18:37:10Z Wikihez 7344 6241567 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Hardcoded fallback list for tr= step — overridden by LangMetadata if loaded. var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; // LangMetadata instance — populated asynchronously after the data script loads. // Use langMeta.getGenders(code) and langMeta.guessScript(code) once available. var langMeta = null; // Maps TranslationAdder-Data gender codes → Kurmancî display labels for zayend. // Extend this dict to support more gender values shown in the data script. var genderLabels = { "m": "Mê", "n": "Nêr", "mn": "Mê û nêr", "nt": "Nêtar", "m-p": "Mê (pirjimar)", "n-p": "Nêr (pirjimar)", "nt-p": "Nêtar (pirjimar)", "g": "Giştî", "g-p": "Giştî (pirjimar)", "y": "Yekjimar", "p": "Pirjimar" }; // Latin-based script codes — languages using these do NOT need tr= transcription. var latinScripts = { Latn: 1, Hebr: 1 }; // Returns true when a language needs manual transcription input. function needsTr(langCode) { if (langMeta && typeof langMeta.getGenders === "function") { var sc = langMeta.guessScript(langCode); if (!sc) return false; return !latinScripts[sc]; } return trRequired.indexOf(langCode) !== -1; } // Returns the zayend choices for the currently selected language. function getZayendChoices(langCode) { if (langMeta && typeof langMeta.getGenders === "function") { var gs = langMeta.getGenders(langCode); if (gs && gs.length) { return gs .filter(function (g) { return genderLabels[g]; }) .map(function (g) { return [g, genderLabels[g]]; }); } return []; } return [["m","Mê"],["n","Nêr"],["mn","Mê û nêr"],["nt","Nêtar"]]; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { if (!(values.lang && (values.pos === "navdêr" || values.pos === "serenav"))) return false; // Hide if LangMetadata says this language has no genders. return getZayendChoices(values.lang).length > 0; }, // choices is populated dynamically via build() using getZayendChoices(). choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], build: function (stepDiv, values) { if (!values || !values.lang) return null; var choices = getZayendChoices(values.lang); var sel = stepDiv.find("#wiktvi-start-zayend-field"); if (!sel.length) { // First build — create the select. sel = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-zayend-field" })); sel.attr("data-placeholder", "Zayend hilbijêre"); if (isMobile) { stepDiv.append(wrapNativeSelect(sel)); } else { stepDiv.append(sel); } } // Repopulate options every time (lang may have changed). populateMenus(sel, choices); if (!isMobile) sel.trigger("chosen:updated"); return isMobile ? null : sel; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTr(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } // Load TranslationAdder-Data.js for dynamic gender and script metadata. // Works whether the script is loaded as a personal script or a gadget. // Once loaded, LangMetadata becomes available on window; instantiate it // and trigger a refresh so zayend/tr steps update immediately. function loadLangMetadata() { if (window.LangMetadata) { try { var inst = new window.LangMetadata(); if (typeof inst.getGenders === "function") { langMeta = inst; refresh(); } } catch (e) {} return; } var gadgetModule = "ext.gadget.TranslationAdder-Data"; var langUtilsModule = "ext.gadget.LanguageUtils"; var userScriptUrl = "https://ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript"; function tryInstantiate() { if (!window.LangMetadata) return; try { var instance = new window.LangMetadata(); // Verify the instance is functional before assigning. if (typeof instance.getGenders === "function") { langMeta = instance; refresh(); } } catch (e) {} } // LanguageUtils must be loaded first — LangMetadata's constructor calls // new ScriptUtils() which lives in that module. mw.loader.using(langUtilsModule).then(function () { // Now try loading the data script as a gadget. mw.loader.using(gadgetModule).then( function () { tryInstantiate(); }, function () { // Gadget not registered — fall back to user script URL. $.getScript(userScriptUrl).done(tryInstantiate); } ); }, function () { // LanguageUtils gadget not found either — just try the data script // directly and hope ScriptUtils is a no-op or already present. $.getScript(userScriptUrl).done(tryInstantiate); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], function () { build(); loadLangMetadata(); }); }); //</nowiki> 2lewr37rnn4bpbldst644qrosyd5ntk 6241569 6241567 2026-07-10T18:40:48Z Wikihez 7344 6241569 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // Hardcoded fallback list for tr= step — overridden by LangMetadata if loaded. var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; // LangMetadata instance — populated asynchronously after the data script loads. // Use langMeta.getGenders(code) and langMeta.guessScript(code) once available. var langMeta = null; // Maps TranslationAdder-Data gender codes → Kurmancî display labels for zayend. // Extend this dict to support more gender values shown in the data script. var genderLabels = { "m": "Mê", "n": "Nêr", "mn": "Mê û nêr", "nt": "Nêtar", "m-p": "Mê (pirjimar)", "n-p": "Nêr (pirjimar)", "nt-p": "Nêtar (pirjimar)", "g": "Giştî", "g-p": "Giştî (pirjimar)", "y": "Yekjimar", "p": "Pirjimar" }; // Latin-based script codes — languages using these do NOT need tr= transcription. var latinScripts = { Latn: 1, Hebr: 1 }; // Returns true when a language needs manual transcription input. function needsTr(langCode) { if (langMeta && typeof langMeta.getGenders === "function") { var sc = langMeta.guessScript(langCode); if (!sc) return false; return !latinScripts[sc]; } return trRequired.indexOf(langCode) !== -1; } // Returns the zayend choices for the currently selected language. function getZayendChoices(langCode) { if (langMeta && typeof langMeta.getGenders === "function") { var gs = langMeta.getGenders(langCode); if (gs && gs.length) { return gs .filter(function (g) { return genderLabels[g]; }) .map(function (g) { return [g, genderLabels[g]]; }); } return []; } return [["m","Mê"],["n","Nêr"],["mn","Mê û nêr"],["nt","Nêtar"]]; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { if (!(values.lang && (values.pos === "navdêr" || values.pos === "serenav"))) return false; // Hide if LangMetadata says this language has no genders. return getZayendChoices(values.lang).length > 0; }, // choices is populated dynamically via build() using getZayendChoices(). choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], build: function (stepDiv, values) { if (!values || !values.lang) return null; var choices = getZayendChoices(values.lang); var sel = stepDiv.find("#wiktvi-start-zayend-field"); if (!sel.length) { // First build — create the select. sel = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-zayend-field" })); sel.attr("data-placeholder", "Zayend hilbijêre"); if (isMobile) { stepDiv.append(wrapNativeSelect(sel)); } else { stepDiv.append(sel); } } // Repopulate options every time (lang may have changed). populateMenus(sel, choices); if (!isMobile) sel.trigger("chosen:updated"); return isMobile ? null : sel; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTr(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } // Load LanguageUtils.js then TranslationAdder-Data.js in sequence. // LanguageUtils must come first because LangMetadata.guessScript calls // new ScriptUtils() which is defined there. Neither is a gadget yet so // both are fetched via $.getScript from the user-script URLs. function loadLangMetadata() { var langUtilsUrl = "https://ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/LanguageUtils.js&action=raw&ctype=text/javascript"; var transDataUrl = "https://ku.wiktionary.org/w/index.php?title=Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js&action=raw&ctype=text/javascript"; function tryInstantiate() { if (!window.LangMetadata) return; try { var instance = new window.LangMetadata(); // getGenders has no external dependency — use it as a smoke test. if (typeof instance.getGenders === "function") { langMeta = instance; refresh(); } } catch (e) {} } // If both scripts are already loaded (e.g. by another gadget), instantiate now. if (window.LangMetadata) { tryInstantiate(); return; } $.getScript(langUtilsUrl).done(function () { $.getScript(transDataUrl).done(tryInstantiate); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], function () { build(); loadLangMetadata(); }); }); //</nowiki> d5woc1hby8n2ehli1zs9z40ffakv7qp 6241570 6241569 2026-07-10T18:44:03Z Wikihez 7344 Restored revision 6241564 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6241570 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] // // Guhertoya revîzekirî — 2026-07-10 // - Sereastkirin: hevoka kurte ya edîtê ("output" li şûna "values.dfn") // - Sereastkirin: pageName nehatibû revandin berî lêkolîna RegExp-ê // - Sereastkirin: "nt" (nêtar) êdî nayê veguherandin bo "mn" di |z=-ê de // - Sereastkirin: mifteya nimûneya paremî "gotineke pêşiyan" e, ne "gp" // (berê negihîştî bû ji ber vê şaşiyê) // - Xurtkirin: têketina bikarhêner tê revandin berî ku bikeve şablonan // (| û = dikarin sazkariya şablonê bişkênin) // - Refaktorkirin: pênc gavên dubare (variant/syn/ant/je/tekildar) bûne // yek fabrîkeya fonksiyonê; mantiqa "bêmînak" a dubarekirî bû yek fonksiyon // - Rakirin: String.prototype.wiktviCapitalize (guherto: capitalize()) // - Rakirin: koda mirî (rowsNimune, output-ên tr/nimune yên qet nayên gazîkirin, // şîroveya {{mẫu}} ya Wîetnamî ya ji orjînalê mabû) // - Regexa navê zimên (header.name.match) hatiye hiştin wek xwe bi qesd // - Xurtkirin: zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json // tên barkirin; -pro û "zimanê destan" tên derxistin // - Xurtkirin: zimanan bi koda zimanî jî tê lêgerandin (mînak "ku" → kurmancî) // - Xurtkirin: hemû qutiyên nivîsê û textareayan dikarin mezin/biçûk bibin // - Refaktorkirin: her mane êdî xweyê nimûne, herwiha, hevmane û dijmaneyên // xwe yên taybet e; gavên serbixwe yên nimûne/herwiha/hevmane/dijmanê hatin // rakirin û di bloka maneyê de yekgirtî bûn //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a peyvê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şîrovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner sazkariya şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lêbigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin pênaseyekê de: an rêzikên "#: {{mk|...}}" * bo her nimûneyekê, an "#* {{bêmînak|lang}}" ger tu nimûne tunebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema pênase heye û dema pênase vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bêmînak|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{mk|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya peyvan" ên hevshibin: herwiha, hevmane, * dijmane, jê, têkildar. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê bilêvkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-IPA}}\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî ya “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["lêker/p", "Lêkera pêkhatî"], ["lêker/b", "Lêkera biwêjî"], ["lêker/x", "Lêkera xwerû"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var zayend = values.zayend || ""; // from the zayend step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && zayend && genderNames[zayend] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[zayend] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (zayend) { outputString += "|z=" + zayend; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|z=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * Zayend (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ zayend: { id: "zayend", name: "zayend", question_fmt: "Zayenda peyvê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ["ngh", "Negerguhêz"], ["x", "Gerguhêz û negerguhêz"] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona peyvê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên peyvê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Nimûne 'serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Peyvên ji bo tiştan (sêv, heywan, qedeh) yan têgihan (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Peyvên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Peyvên yên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Peyvên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Peyvên ku cih, dem yan tevgerê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Peyvên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Peyvên ku hest, deng hwd. derdibirin wekî 'noşî!' yan 'aferîn'!", "pêşgir": "ne-.", "paşgir": "-van.", "serenav": "Navdêrên ku kesayetiyên ferdî nîşan didin, wek navên kes, cih an rêxistinan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Serê neêşe ne hewceyî destmalê ye." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rez", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bêmînak. text = "# {{mane?|" + lang + "}}\n#* {{bêmînak|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Peyvên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Peyvên têkildarî vê peyvê binivîse", "Têkildar", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Ziman hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Werger…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.zayend, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina gotareke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtin"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> m6uoa481aljiujr9bhjt796qvm1hgvg 6241571 6241570 2026-07-10T19:27:05Z Wikihez 7344 6241571 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through ext.gadget.headers. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binereherwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> hx2lbojx907ea2zfxfg9n3uarpc8vtp 6241572 6241571 2026-07-10T19:28:46Z Wikihez 7344 6241572 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binereherwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> ponzthqg4i1prol6jix8vxmyizl379h 6241573 6241572 2026-07-10T19:33:26Z Wikihez 7344 6241573 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> k36sg4hz4vlash7202kutyha47wsieb 6241574 6241573 2026-07-10T19:42:16Z Wikihez 7344 6241574 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr", nt: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku çawaniya navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 222nf4homrmstwkpyi22e1jo44ctxz5 6241575 6241574 2026-07-10T19:47:32Z Wikihez 7344 6241575 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. choices: [ ["navdêr", "Navdêr"], ["lêker", "Lêker"], ["rengdêr", "Rengdêr"], ["hoker", "Hoker"], ["serenav", "Serenav"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj"], ["cînav", "Cînav"], ["daçek", "Daçek"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr", nt: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> cytvd2gopslk96srb5kxllqwj71oybt 6241576 6241575 2026-07-10T19:59:38Z Wikihez 7344 6241576 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var trRequired = ["ckb", "sdh", "ar", "akk", "fa", "ja", "zh", "ru", "ko", "el", "hy", "ka"]; /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj (tabîr)"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr", nt: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr and serenav. * Extend the choices dict here to add more genders in the future. */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { return values.lang && (values.pos === "navdêr" || values.pos === "serenav"); }, // Dictionary: value → display label. Add new genders here. choices: [ ["m", "Mê"], ["n", "Nêr"], ["mn", "Mê û nêr"], ["nt", "Nêtar"] ], output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && trRequired.includes(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 6wiihhtdnyynx9pbhdufpgn079ky5yl 6241577 6241576 2026-07-10T20:10:26Z Wikihez 7344 6241577 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; // `metadata` (nav bi kod, nirx bi {haswikt, sc, g, alt} hwd.) tê danîn li // dawiya pelê — ev tenê valahiyeke pêşdibistanî ye daku skrîpt berî ku ew // tabloya mezin were zêdekirin jî bêyî xeletî bimeşe. var metadata = {}; /** * Ma zimanê bi vî kodî ji bo transkrîpsiyonê (tr=) pêwîstiya wê heye? * Berê rêzek zimanan bi destan hatibû danîn; niha ev ji tîpguhêziya * (script) di metadata de tê wergirtin — ger tîpguhêziya sereke ya * zimên ne latînî be, transkrîpsiyon pêwîst e. */ function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "Mê", n: "Nêr", nt: "Nêtar", mn: "Mê û nêr", c: "Mê û nêr" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (alem)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj (tabîr)"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (herfa cer)"], ["girêdek", "Girêdek (herfa atif)"], ["gotineke pêşiyan","Gotineke pêşiyan (mesel)"], ["hejmar", "Hejmar (aded)"], ["hevok", "Hevok (cumle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav (îhtîsar)"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek (edat)"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek (herfa cer)"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik (herf)"], ["reh", "Reh (cezr)"], ["sembol", "Sembol (remz)"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 8g5kk535wh987fwrzsezcseigqv9fq6 6241578 6241577 2026-07-10T20:17:04Z Wikihez 7344 6241578 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m","n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["biwêj", "Biwêj (tabîr)"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> k4xh2om8fp4x6dsmwpz1i1cm2l236fa 6241580 6241578 2026-07-10T20:27:38Z Wikihez 7344 6241580 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m","n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "Navdêr (îsm) — sêv, heywan, bextiyarî"], ["lêker", "Lêker (fiîl) — baz dan, xwarin, kirin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik, baş"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Bedirxan, Memo"], ["artîkel", "Artîkel — the, das, a"], ["baneşan", "Baneşan (nîda) — ox, ax, hey wax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu, em"], ["daçek", "Daçek (edat) — li, de, ji"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve, re"], ["paşgir", "Paşgir — -van, -ker, -lojî"], ["pêşdaçek", "Pêşdaçek — li, di, bi"], ["pêşgir", "Pêşgir — a-, ne-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 0gl9qxr3yv4njf9aa6x208aad8msroi 6241581 6241580 2026-07-10T20:29:39Z Wikihez 7344 6241581 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m","n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "<code>Navdêr</code> (îsm) — sêv, heywan, bextiyarî"], ["lêker", "<code>Lêker</code> (fiîl) — baz dan, xwarin, kirin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik, baş"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Bedirxan, Memo"], ["artîkel", "Artîkel — the, das, a"], ["baneşan", "Baneşan (nîda) — ox, ax, hey wax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu, em"], ["daçek", "Daçek (edat) — li, de, ji"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve, re"], ["paşgir", "Paşgir — -van, -ker, -lojî"], ["pêşdaçek", "Pêşdaçek — li, di, bi"], ["pêşgir", "Pêşgir — a-, ne-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> srvhfax70qkc57fzkwq47lfc2tj6ysn 6241582 6241581 2026-07-10T20:30:12Z Wikihez 7344 6241582 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m","n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "<b>Navdêr</b> (îsm) — sêv, heywan, bextiyarî"], ["lêker", "<code>Lêker</code> (fiîl) — baz dan, xwarin, kirin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik, baş"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Bedirxan, Memo"], ["artîkel", "Artîkel — the, das, a"], ["baneşan", "Baneşan (nîda) — ox, ax, hey wax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu, em"], ["daçek", "Daçek (edat) — li, de, ji"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve, re"], ["paşgir", "Paşgir — -van, -ker, -lojî"], ["pêşdaçek", "Pêşdaçek — li, di, bi"], ["pêşgir", "Pêşgir — a-, ne-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> mx396lisawv05l2ld3fhzitt5dohfnt 6241583 6241582 2026-07-10T20:33:10Z Wikihez 7344 6241583 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "<b>Navdêr</b> (îsm) — sêv, heywan, bextiyarî"], ["lêker", "<code>Lêker</code> (fiîl) — baz dan, xwarin, kirin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik, baş"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Bedirxan, Memo"], ["artîkel", "Artîkel — the, das, a"], ["baneşan", "Baneşan (nîda) — ox, ax, hey wax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu, em"], ["daçek", "Daçek (edat) — li, de, ji"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve, re"], ["paşgir", "Paşgir — -van, -ker, -lojî"], ["pêşdaçek", "Pêşdaçek — li, di, bi"], ["pêşgir", "Pêşgir — a-, ne-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 1p9aq1xr2hsvy02hepng8c23uzrpm5t 6241584 6241583 2026-07-10T20:34:10Z Wikihez 7344 6241584 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "Navdêr (îsm) — sêv, heywan, bextiyarî"], ["lêker", "Lêker (fiîl) — baz dan, xwarin, kirin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik, baş"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Bedirxan, Memo"], ["artîkel", "Artîkel — the, das, a"], ["baneşan", "Baneşan (nîda) — ox, ax, hey wax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu, em"], ["daçek", "Daçek (edat) — li, de, ji"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve, re"], ["paşgir", "Paşgir — -van, -ker, -lojî"], ["pêşdaçek", "Pêşdaçek — li, di, bi"], ["pêşgir", "Pêşgir — a-, ne-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> flv7jye1wmq27rlqks6800lxlvz0l86 6241585 6241584 2026-07-10T20:35:41Z Wikihez 7344 6241585 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, // Bare POS types only — gender/transitivity are separate steps below. // Navê duyem di navbeynê de nîşana term a hevwate ya erebî/osmanî ye, // tenê ji bo ronîkirinê — mifteya rastîn (element[0]) neguherî ye, // loma sernavên beşan û navên şablonan wek berê dimînin. // Ji bo çend têgehên rêzimana rojavayî (curenav, girêdayîdaçek, // navgir, pêş-/paşgir) di kevneşopiya rêzimana erebî-osmanî de // hevwateyeke rasterast tuneye; ew bêyî parantêz hatine hiştin. choices: [ ["navdêr", "Navdêr (îsm) — sêv, heywan"], ["lêker", "Lêker (fiîl) — baz dan, xwarin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Memo,"], ["artîkel", "Artîkel — the, das"], ["baneşan", "Baneşan (nîda) — ox, ax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu"], ["daçek", "Daçek (edat) — li, de"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve"], ["paşgir", "Paşgir — -van, -lojî"], ["pêşdaçek", "Pêşdaçek — li, bi"], ["pêşgir", "Pêşgir — a-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koord", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var out = "# " + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); out += wordLine("dijmane", sense.dijmane); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> kyh5slghu39f7ftebsu4bkvkzx7iglu 6241586 6241585 2026-07-10T20:48:27Z Wikihez 7344 6241586 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm) — sêv, heywan"], ["lêker", "Lêker (fiîl) — baz dan, xwarin"], ["rengdêr", "Rengdêr (sifet) — sor, xweşik"], ["hoker", "Hoker (zerf) — zû, jêr, îro "], ["serenav", "Serenav (îsmê xisûsî) — Alî, Memo,"], ["artîkel", "Artîkel — the, das"], ["baneşan", "Baneşan (nîda) — ox, ax"], ["bazinedaçik", "Bazinedaçek — di...de"], ["cînav", "Cînav (zemîr) — ez, tu"], ["daçek", "Daçek (edat) — li, de"], ["girêdek", "Girêdek — û, feqat"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar — yek, didu"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir — -e-"], ["paşdaçek", "Paşdaçek — de, ve"], ["paşgir", "Paşgir — -van, -lojî"], ["pêşdaçek", "Pêşdaçek — li, bi"], ["pêşgir", "Pêşgir — a-, bê"], ["pirtik", "Pirtik"], ["reh", "Reh — -bêj-, -hêl-"], ["sembol", "Sembol"], ["tîp", "Tîp (herf) — X, W, Q"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("+ Etîketê lê zêde bike"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = "{{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> pl6xlo6at1sv7bqcgt96fu4masx2xgj 6241587 6241586 2026-07-10T20:53:13Z Wikihez 7344 6241587 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("+ Etîketê lê zêde bike"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = "{{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> ri0bl7ixvoswjmotcxyupjx5wbxpy8h 6241588 6241587 2026-07-10T20:54:09Z Wikihez 7344 6241588 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("+ Etîketê lê zêde bike"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> ozqnu2wncmbk2pvpm4vghh1t671hd7p 6241590 6241588 2026-07-10T21:17:45Z Wikihez 7344 6241590 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("+ Etîketê lê zêde bike"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> a632v4s2z7nwtbt1bjdhv8fysksseey 6241591 6241590 2026-07-10T21:33:22Z Wikihez 7344 Restored revision 6241588 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6241591 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("+ Etîketê lê zêde bike"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkbox ───────────────────────────────────────────────── var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); var previewTimer = null; function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); }); }, 400); } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); } }); // Listen on all input/change events on the form and update the preview. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview panel after the form now that startForm is in the DOM. startForm.after(previewPanel); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> ozqnu2wncmbk2pvpm4vghh1t671hd7p 6241592 6241591 2026-07-10T22:27:03Z Wikihez 7344 6241592 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("+ Etîketê lê zêde bike"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true } ]; $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> r96nr72lm5l3vlxfn3a9xy0oxwd84gm 6241593 6241592 2026-07-10T22:31:51Z Wikihez 7344 6241593 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle {" + " display: inline-block;" + " margin: 2px 0 6px;" + " font-size: 0.85em;" + "}" + "input.wiktvi-dfn-label-field {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + " margin-bottom: 6px;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Etîket (label) link + hidden field — // {{e|lang|label1|label2}} tê danîn di navbera "#" û manê de. // Bişkoja "+ Etîketê lê zêde bike" qutiya nivîsê vedike/dadixe; // tişta hundir de bi "|" tê veqetandin (mînak: anatomî|heywan|û|Amed). var labelToggle = $("<a href='#'></a>") .addClass("wiktvi-dfn-label-toggle") .text("(+ Etîket)"); var labelInput = $("<input type='text'>") .addClass("wiktvi-dfn-label-field") .attr("placeholder", "Etîketekê lê zêde bike wek: anatomî|heywan|û|Amed") .hide(); labelToggle.on("click", function (evt) { evt.preventDefault(); labelInput.toggle(); if (labelInput.is(":visible")) labelInput.focus(); }); block.append(labelToggle).append(labelInput); // — Sub-field groups (nimûne, herwiha, hevmane, dijmane) — // nimûne is always visible; the rest are hidden behind a click-to-add link. var subGroups = [ { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; // Inline link row that holds all lazy-group triggers. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); $.each(subGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — original behaviour. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — show only a "(+ Label)" link; reveal the field on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); // Remove the link from the links row. addLink.remove(); // Build the group inline. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert the group before the lazy-links row so order is preserved. lazyLinksDiv.before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); block.append(lazyLinksDiv); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = $.trim(block.find("input.wiktvi-dfn-label-field").val()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket) { var labelParts = $.grep(sense.etiket.split("|"), function (part) { return $.trim(part) !== ""; }).map(function (part) { return escapeTemplateParam($.trim(part)); }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> cdpfmqikwvqdct7phle0rbod2yk50rj 6241594 6241593 2026-07-10T22:36:30Z Wikihez 7344 6241594 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // All lazy fields are revealed by clicking their respective link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); // — Sub-field groups — // nimûne: always visible. // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true, isEtiket: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne). var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Nimûne goes directly into the block, before the links row. block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before the links row to keep visual order. lazyLinksDiv.before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); block.append(lazyLinksDiv); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> sdzz4tokms963wqe5k64bzsuvovkpii 6241595 6241594 2026-07-10T22:39:05Z Wikihez 7344 6241595 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); block.append(dfnArea); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; var hasMane = senses.some(function (s) { return s.mane !== ""; }); var text = $.map(senses, function (sense) { var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} — kesk parçeyên di navbera "|" // de tên veqetandin, her yek jê tê revandin ji ber "=". var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { return values.lang === "ku" && values.pos; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 6exrqkagcjiibo6fdqgsneud2vu9wb3 6241596 6241595 2026-07-10T22:46:56Z Wikihez 7344 6241596 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" + ".wiktvi-dfn-tpl-row {" + " margin-bottom: 4px;" + "}" + ".wiktvi-dfn-tpl-select {" + " font-size: 0.9em;" + "}" + "input.wiktvi-dfn-tpl-title {" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — var tplNames = [ "Guharto", "Hevmaneya", "Awayekî din", "Pirjimar", "Romanization", "Awayê Jacobsonê", "ku-Latn", "ku-Arab", "ckb-Latn", "ckb-Arab" ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplNames, function (_, name) { tplSelect.append($("<option></option>").val(name).text(name)); }); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var tpl = block.find("select.wiktvi-dfn-tpl-select").val() || ""; var tplTitle = $.trim(block.find("input.wiktvi-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ tpl: tpl, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has either a mane or a chosen template + title. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{Guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } // — Normal mane sense — var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger when at least one sense uses a template instead of a mane. var hasTemplateSense = false; $("#wiktvi-start-dfn li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTemplateSense = true; return false; // break } }); return !hasTemplateSense; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 6o1zij34btw1o9siltu2vyxikjlwx55 6241597 6241596 2026-07-10T22:50:33Z Wikihez 7344 6241597 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" + ".wiktvi-dfn-tpl-row {" + " margin-bottom: 4px;" + "}" + ".wiktvi-dfn-tpl-select {" + " font-size: 0.9em;" + "}" + "input.wiktvi-dfn-tpl-title {" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — var tplNames = [ "Guharto", "Hevmaneya", "Awayekî din", "Pirjimar", "Romanization", "Awayê Jacobsonê", "ku-Latn", "ku-Arab", "ckb-Latn", "ckb-Arab" ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplNames, function (_, name) { tplSelect.append($("<option></option>").val(name).text(name)); }); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var tpl = block.find("select.wiktvi-dfn-tpl-select").val() || ""; var tplTitle = $.trim(block.find("input.wiktvi-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ tpl: tpl, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has either a mane or a chosen template + title. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{Guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } // — Normal mane sense — var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger when at least one sense uses a template instead of a mane. var hasTemplateSense = false; $("#wiktvi-start-dfn li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTemplateSense = true; return false; // break } }); return !hasTemplateSense; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> qlnd24wyc2a82sm6xrtzisyyee7o11o 6241598 6241597 2026-07-10T22:56:46Z Wikihez 7344 6241598 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" + ".wiktvi-dfn-tpl-row {" + " margin-bottom: 4px;" + "}" + ".wiktvi-dfn-tpl-select {" + " font-size: 0.9em;" + "}" + "input.wiktvi-dfn-tpl-title {" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // langs: null = all languages, otherwise array of allowed lang codes. var tplDefs = [ { name: "Guharto", langs: null }, { name: "Hevmaneya", langs: null }, { name: "Awayekî din", langs: null }, { name: "Pirjimar", langs: null }, { name: "Romanization", langs: null }, { name: "Awayê Jacobsonê", langs: ["zza"] }, { name: "ku-Latn", langs: ["ku"] }, { name: "ku-Arab", langs: ["ku"] }, { name: "ckb-Latn", langs: ["ckb"] }, { name: "ckb-Arab", langs: ["ckb"] } ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { tplSelect.append( $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") ); }); // Shows only options valid for the current lang; resets selection if // the currently chosen template is no longer valid. function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; tplSelect.find("option[value!='']").each(function () { var allowed = $(this).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; $(this).toggle(visible); if ($(this).val() === currentVal && visible) currentStillValid = true; }); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var tpl = block.find("select.wiktvi-dfn-tpl-select").val() || ""; var tplTitle = $.trim(block.find("input.wiktvi-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ tpl: tpl, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has either a mane or a chosen template + title. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{Guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } // — Normal mane sense — var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger when at least one sense uses a template instead of a mane. var hasTemplateSense = false; $("#wiktvi-start-dfn li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTemplateSense = true; return false; // break } }); return !hasTemplateSense; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktvi-start-dfn .wiktvi-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktvi-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 7hmuf8illgbfgmco72cszlqmdrveuo3 6241599 6241598 2026-07-10T23:04:35Z Wikihez 7344 6241599 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" + ".wiktvi-dfn-tpl-row {" + " margin-bottom: 4px;" + "}" + ".wiktvi-dfn-tpl-select {" + " font-size: 0.9em;" + "}" + "input.wiktvi-dfn-tpl-title {" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + ".wiktvi-pos-section {" + " border-left: 3px solid #a2a9b1;" + " margin-top: 1em;" + " padding-left: 0.8em;" + "}" + ".wiktvi-pos-section-header {" + " display: flex;" + " align-items: center;" + " gap: 0.5em;" + " margin-bottom: 0.3em;" + " font-weight: bold;" + " font-size: 0.9em;" + " color: #555;" + "}" + "button.wiktvi-remove-section {" + " font-size: 0.8em;" + " padding: 1px 6px;" + " cursor: pointer;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // langs: null = all languages, otherwise array of allowed lang codes. var tplDefs = [ { name: "Guharto", langs: null }, { name: "Hevmaneya", langs: null }, { name: "Awayekî din", langs: null }, { name: "Pirjimar", langs: null }, { name: "Romanization", langs: null }, { name: "Awayê Jacobsonê", langs: ["zza"] }, { name: "ku-Latn", langs: ["ku"] }, { name: "ku-Arab", langs: ["ku"] }, { name: "ckb-Latn", langs: ["ckb"] }, { name: "ckb-Arab", langs: ["ckb"] } ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { tplSelect.append( $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") ); }); // Shows only options valid for the current lang; resets selection if // the currently chosen template is no longer valid. function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; tplSelect.find("option[value!='']").each(function () { var allowed = $(this).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; $(this).toggle(visible); if ($(this).val() === currentVal && visible) currentStillValid = true; }); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var tpl = block.find("select.wiktvi-dfn-tpl-select").val() || ""; var tplTitle = $.trim(block.find("input.wiktvi-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ tpl: tpl, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has either a mane or a chosen template + title. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{Guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } // — Normal mane sense — var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger when at least one sense uses a template instead of a mane. var hasTemplateSense = false; $("#wiktvi-start-dfn li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTemplateSense = true; return false; // break } }); return !hasTemplateSense; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; // ── Extra sections (additional Cureyê rêzimanî blocks) ────────────────── // Each extra section is a self-contained object built by createSection(). // It owns its own suffixed DOM IDs and step logic, and reads lang from // section 0 via getSharedValues(). var extraSections = []; function createSection(suffix, getSharedValues) { // id() maps a bare step id to the suffixed DOM id used by this section. function sid(id) { return id + suffix; } function domId(id) { return "wiktvi-start-" + sid(id); } function sel(id) { return "#" + domId(id); } // Per-section makeWordListStep (references sec.steps for output values) function secWordListStep(id, name, question_fmt, header, templateName) { return { id: sid(id), name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (sv) { return sv.lang && sv[sid("pos")]; }, output: function (sv) { var words = sv[sid(id)]; if (!words || !words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + sv.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var sec = {}; sec.steps = { pos: { id: sid("pos"), required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê "{{PAGENAME}}" çi ye?", visible: function (sv) { return sv.lang; }, question_br: true, choices: steps.pos.choices, output: function (sv) { var pos = sv[sid("pos")] || ""; var cinsiyet = sv[sid("cinsiyet")] || ""; var lekTur = sv[sid("lektur")] || ""; var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && sv.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + sv.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (sv.lang === "ku") { outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (sv[sid("tr")]) { outputString += "|tr=" + escapeTemplateParam(sv[sid("tr")]); } outputString += "}}\n"; return outputString; } }, cinsiyet: { id: sid("cinsiyet"), name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (sv) { var meta = metadata[sv.lang]; return !!(sv.lang && (sv[sid("pos")] === "navdêr" || sv[sid("pos")] === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, sv) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: domId("cinsiyet") + "-field" })); stepDiv.append(select); } if (!sv) return select; var meta = metadata[sv.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) select.val(prevVal); if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } }, lektur: { id: sid("lektur"), name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (sv) { return sv.lang && sv[sid("pos")] && /^lêker/.test(sv[sid("pos")]); }, choices: steps.lektur.choices, output: function () { return ""; } }, tr: { id: sid("tr"), name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (sv) { return sv.lang && sv[sid("pos")] && needsTransliteration(sv.lang); } }, dfn: { id: sid("dfn"), name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (sv) { return sv.lang && sv[sid("pos")]; }, example: steps.dfn.example, buildSenseBlock: function (stepDiv) { // Reuse the shared buildSenseBlock but with this section's getValues // for tplSelect's updateTplOptions. var block = $("<li class='wiktvi-dfn-sense'></li>"); var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3).attr("placeholder", "Mane…"); dfnArea.on("input", function () { sec.steps.dfn.onDfnInput(stepDiv, block, this); }); var tplDefs = [ { name: "Guharto", langs: null }, { name: "Hevmaneya", langs: null }, { name: "Awayekî din", langs: null }, { name: "Pirjimar", langs: null }, { name: "Romanization", langs: null }, { name: "Awayê Jacobsonê", langs: ["zza"] }, { name: "ku-Latn", langs: ["ku"] }, { name: "ku-Arab", langs: ["ku"] }, { name: "ckb-Latn", langs: ["ckb"] }, { name: "ckb-Arab", langs: ["ckb"] } ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { tplSelect.append($("<option></option>").val(tpl.name).text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "")); }); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…").hide(); function updateTplOptions() { var lang = sec.getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; tplSelect.find("option[value!='']").each(function () { var allowed = $(this).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; $(this).toggle(visible); if ($(this).val() === currentVal && visible) currentStillValid = true; }); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } tplSelect.data("updateOptions", updateTplOptions); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } sec.refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow).append(dfnArea); updateTplOptions(); var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var fi = $("<textarea></textarea>").attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); fi.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(fi)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { var addLink = $("<a href='#'></a>").addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var fi = $("<textarea></textarea>").attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); fi.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(fi)); groupDiv.append(lbl).append(list); block.find(".wiktvi-dfn-nimune-group").before(groupDiv); fi.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { list.append(sec.steps.dfn.buildSenseBlock(stepDiv)); } sec.refresh(); }, onSubInput: steps.dfn.onSubInput, build: function (stepDiv) { if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(sec.steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, getSenses: steps.dfn.getSenses, getOutput: function (sv, callback) { var stepDiv = $(sel("dfn")); var senses = sec.steps.dfn.getSenses(stepDiv); var lang = sv.lang; var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } var dfn = sense.mane; if (!dfn) return undefined; if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var lp = sense.etiket.map(function (p) { return escapeTemplateParam($.trim(p)); }) .filter(function (p) { return p !== ""; }); if (lp.length) labelTpl = " {{e|" + lang + "|" + lp.join("|") + "}} "; } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += formatNimune(sense.nimune, lang); function wl(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wl("herwiha-rêz", sense.herwiha); out += wl("hevmane", sense.hevmane); out += wl("dijmane", sense.dijmane); out += wl("termên koordîne", sense.koordine); out += wl("jornav", sense.jornav); out += wl("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { callback(text); return; } var done = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", done, done); } }, je: secWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: secWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: secWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: sid("etym"), name: "etîmolojî", visible: function () { return false; }, output: function (sv) { return sv.lang === "ku" ? "==== Etîmolojî ====\n{{ji?|ku}}" : ""; } }, trans: { id: sid("trans"), name: "werger", visible: function (sv) { if (!(sv.lang === "ku" && sv[sid("pos")])) return false; var hasTpl = false; $(sel("dfn") + " li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTpl = true; return false; } }); return !hasTpl; }, disabledKeys: { "navz": true, "ku": true }, buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, sec.steps.trans.keys || [], sec.steps.trans.disabledKeys); langSel.on("change", function () { sec.steps.trans.onLangChange(stepDiv, row); }); var wordList = $("<ul class='wiktvi-trans-words'></ul>"); wordList.append($("<li></li>").append(sec.steps.trans.makeWordInput())); if (isMobile) row.append(wrapNativeSelect(langSel)).append(wordList); else row.append(langSel).append(wordList); return row; }, makeWordInput: steps.trans.makeWordInput, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); if (row.is(list.children("li.wiktvi-trans-row:last-child"))) { var nr = sec.steps.trans.buildRow(stepDiv); list.append(nr); if (!isMobile) nr.find("select").chosen(chosenOptions); } sec.steps.trans.syncDisabledKeys(stepDiv); }, syncDisabledKeys: steps.trans.syncDisabledKeys, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(sec.steps.trans.buildRow(stepDiv)); stepDiv.append(list); if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, getTranslations: steps.trans.getTranslations, output: function (sv) { if (sv.lang !== "ku") return ""; var stepDiv = $(sel("trans")); var rows = steps.trans.getTranslations(stepDiv); var out = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { rows.sort(function (a, b) { return (langsByCode[a[0]] && langsByCode[a[0]][2] || "") .localeCompare((langsByCode[b[0]] && langsByCode[b[0]][2] || ""), "ku"); }); out += "\n" + $.map(rows, function (row) { return "* {{Z|" + row[0] + "}}: " + row[1].map(escapeTemplateParam) .map(function (w) { return "{{W|" + row[0] + "|" + w + "}}"; }).join(", "); }).join("\n"); } out += "\n{{werger-bin}}\n\n"; return out; } } }; sec.steps.trans.keys = steps.trans.keys; sec.orderedSteps = [ sec.steps.pos, sec.steps.cinsiyet, sec.steps.lektur, sec.steps.tr, sec.steps.dfn, sec.steps.je, sec.steps.tekildar, sec.steps.binereherwiha, sec.steps.etym, sec.steps.trans ]; // Per-section getValues — merges shared lang into its own step values. sec.getValues = function () { var sv = $.extend({}, getSharedValues()); $.each(sec.steps, function (_, step) { var fields = $(sel(step.id.replace(suffix, "")) + " .wiktvi-start-step-field"); // For steps with a custom id already suffixed, use the full id DOM selector. fields = $("#" + "wiktvi-start-" + step.id + " .wiktvi-start-step-field"); if (step.keys) { var vals = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) vals[key] = $(field).val(); }); sv[step.id] = vals; } else if (step.multiple) { sv[step.id] = fields.map(function () { return $(this).val(); }).get(); } else { sv[step.id] = fields.val(); } }); return sv; }; // Per-section refresh — updates visibility and builds for this section's steps only. sec.refresh = function () { var sv = sec.getValues(); $(sel("dfn") + " .wiktvi-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); $.each(sec.steps, function (_, step) { var stepDiv = $("#wiktvi-start-" + step.id); if (typeof step.visible === "function" && !step.visible(sv)) { stepDiv.slideUp(); } else { if (typeof step.build === "function") { prepareInput(step.build(stepDiv, sv), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof step.example === "function") { input.attr("placeholder", step.example(sv) || ""); } stepDiv.slideDown(); } }); }; // Builds the section DOM block and appends it to the form. sec.buildDOM = function (startForm) { var wrapper = $("<div></div>") .addClass("wiktvi-pos-section") .attr("id", "wiktvi-pos-section" + suffix); var header = $("<div></div>").addClass("wiktvi-pos-section-header"); header.append("Beşa din — Cureyê rêzimanî"); var removeBtn = $("<button type='button'></button>") .addClass("wiktvi-remove-section").text("× Rake"); removeBtn.on("click", function () { wrapper.remove(); extraSections = $.grep(extraSections, function (s) { return s !== sec; }); }); header.append(removeBtn); wrapper.append(header); $.each(sec.orderedSteps, function (_, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) stepDiv.append(wrapNativeSelect(input)); else stepDiv.append(input); } else if (typeof step.build === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else { stepDiv.append(input); } } if (input) { if (step.required) input.prop("required", true); // On change, run this section's own refresh. input.on("change", function () { sec.refresh(); }); } stepDiv.hide(); wrapper.append(stepDiv); }); startForm.find("#wiktvi-start-footer").before(wrapper); if (!isMobile) wrapper.find("select.wiktvi-start-step-field").chosen(chosenOptions); // Listen to all input/change inside the section wrapper. wrapper.on("input change", function () { sec.refresh(); }); sec.refresh(); }; // Produces the wikitext for this section (chained async via callback). sec.getOutput = function (callback) { var sv = sec.getValues(); if (!sv[sid("pos")]) { callback(""); return; } var entry = sec.steps.pos.output(sv); sec.steps.dfn.getOutput(sv, function (dfnOut) { entry += dfnOut; entry += sec.steps.je.output(sv); entry += sec.steps.tekildar.output(sv); entry += sec.steps.binereherwiha.output(sv); entry += sec.steps.etym.output(sv); entry += sec.steps.trans.output(sv); callback(entry); }); }; return sec; } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); // Chain extra sections sequentially then fire callback. function appendExtraSections(idx) { if (idx >= extraSections.length) { var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); return; } extraSections[idx].getOutput(function (secOut) { entry += secOut; appendExtraSections(idx + 1); }); } appendExtraSections(0); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktvi-start-dfn .wiktvi-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); // Propagate lang change to all extra sections. $.each(extraSections, function (_, sec) { sec.refresh(); }); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktvi-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); var addSectionBtn = $(mw.html.element("button", { id: "wiktvi-add-section", type: "button" }, "+ Beşa din lê zêde bike")); addSectionBtn.css("margin-left", "6px"); addSectionBtn.on("click", function () { var suffix = "_s" + (extraSections.length + 2); var sec = createSection(suffix, getValues); extraSections.push(sec); sec.buildDOM(startForm); }); footer.append(addSectionBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> dp8vyzj77hp8s3d6mqgqhg1fhbvqbcs 6241600 6241599 2026-07-10T23:07:59Z Wikihez 7344 6241600 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" + ".wiktvi-dfn-tpl-row {" + " margin-bottom: 4px;" + "}" + ".wiktvi-dfn-tpl-select {" + " font-size: 0.9em;" + "}" + "input.wiktvi-dfn-tpl-title {" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + ".wiktvi-pos-section {" + " border-left: 3px solid #a2a9b1;" + " margin-top: 1em;" + " padding-left: 0.8em;" + "}" + ".wiktvi-pos-section-header {" + " display: flex;" + " align-items: center;" + " gap: 0.5em;" + " margin-bottom: 0.3em;" + " font-weight: bold;" + " font-size: 0.9em;" + " color: #555;" + "}" + "button.wiktvi-remove-section {" + " font-size: 0.8em;" + " padding: 1px 6px;" + " cursor: pointer;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // langs: null = all languages, otherwise array of allowed lang codes. var tplDefs = [ { name: "Guharto", langs: null }, { name: "Hevmaneya", langs: null }, { name: "Awayekî din", langs: null }, { name: "Pirjimar", langs: null }, { name: "Romanization", langs: null }, { name: "Awayê Jacobsonê", langs: ["zza"] }, { name: "ku-Latn", langs: ["ku"] }, { name: "ku-Arab", langs: ["ku"] }, { name: "ckb-Latn", langs: ["ckb"] }, { name: "ckb-Arab", langs: ["ckb"] } ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { tplSelect.append( $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") ); }); // Shows only options valid for the current lang; resets selection if // the currently chosen template is no longer valid. function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; tplSelect.find("option[value!='']").each(function () { var allowed = $(this).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; $(this).toggle(visible); if ($(this).val() === currentVal && visible) currentStillValid = true; }); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var tpl = block.find("select.wiktvi-dfn-tpl-select").val() || ""; var tplTitle = $.trim(block.find("input.wiktvi-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ tpl: tpl, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has either a mane or a chosen template + title. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{Guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } // — Normal mane sense — var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger when at least one sense uses a template instead of a mane. var hasTemplateSense = false; $("#wiktvi-start-dfn li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTemplateSense = true; return false; // break } }); return !hasTemplateSense; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; // ── Extra sections (additional Cureyê rêzimanî blocks) ────────────────── // Each extra section is a self-contained object built by createSection(). // It owns its own suffixed DOM IDs and step logic, and reads lang from // section 0 via getSharedValues(). var extraSections = []; function createSection(suffix, getSharedValues) { // id() maps a bare step id to the suffixed DOM id used by this section. function sid(id) { return id + suffix; } function domId(id) { return "wiktvi-start-" + sid(id); } function sel(id) { return "#" + domId(id); } // Per-section makeWordListStep (references sec.steps for output values) function secWordListStep(id, name, question_fmt, header, templateName) { return { id: sid(id), name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (sv) { return sv.lang && sv[sid("pos")]; }, output: function (sv) { var words = sv[sid(id)]; if (!words || !words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + sv.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var sec = {}; sec.steps = { pos: { id: sid("pos"), required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê '{{PAGENAME}}' çi ye?", visible: function (sv) { return sv.lang; }, question_br: true, choices: steps.pos.choices, output: function (sv) { var pos = sv[sid("pos")] || ""; var cinsiyet = sv[sid("cinsiyet")] || ""; var lekTur = sv[sid("lektur")] || ""; var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && sv.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + sv.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (sv.lang === "ku") { outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (sv[sid("tr")]) { outputString += "|tr=" + escapeTemplateParam(sv[sid("tr")]); } outputString += "}}\n"; return outputString; } }, cinsiyet: { id: sid("cinsiyet"), name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (sv) { var meta = metadata[sv.lang]; return !!(sv.lang && (sv[sid("pos")] === "navdêr" || sv[sid("pos")] === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, sv) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: domId("cinsiyet") + "-field" })); stepDiv.append(select); } if (!sv) return select; var meta = metadata[sv.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) select.val(prevVal); if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } }, lektur: { id: sid("lektur"), name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (sv) { return sv.lang && sv[sid("pos")] && /^lêker/.test(sv[sid("pos")]); }, choices: steps.lektur.choices, output: function () { return ""; } }, tr: { id: sid("tr"), name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (sv) { return sv.lang && sv[sid("pos")] && needsTransliteration(sv.lang); } }, dfn: { id: sid("dfn"), name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse.", multiple: true, ordered: true, rows: 3, visible: function (sv) { return sv.lang && sv[sid("pos")]; }, example: steps.dfn.example, buildSenseBlock: function (stepDiv) { // Reuse the shared buildSenseBlock but with this section's getValues // for tplSelect's updateTplOptions. var block = $("<li class='wiktvi-dfn-sense'></li>"); var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3).attr("placeholder", "Mane…"); dfnArea.on("input", function () { sec.steps.dfn.onDfnInput(stepDiv, block, this); }); var tplDefs = [ { name: "Guharto", langs: null }, { name: "Hevmaneya", langs: null }, { name: "Awayekî din", langs: null }, { name: "Pirjimar", langs: null }, { name: "Romanization", langs: null }, { name: "Awayê Jacobsonê", langs: ["zza"] }, { name: "ku-Latn", langs: ["ku"] }, { name: "ku-Arab", langs: ["ku"] }, { name: "ckb-Latn", langs: ["ckb"] }, { name: "ckb-Arab", langs: ["ckb"] } ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { tplSelect.append($("<option></option>").val(tpl.name).text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "")); }); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…").hide(); function updateTplOptions() { var lang = sec.getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; tplSelect.find("option[value!='']").each(function () { var allowed = $(this).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; $(this).toggle(visible); if ($(this).val() === currentVal && visible) currentStillValid = true; }); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } tplSelect.data("updateOptions", updateTplOptions); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } sec.refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow).append(dfnArea); updateTplOptions(); var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var fi = $("<textarea></textarea>").attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); fi.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(fi)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { var addLink = $("<a href='#'></a>").addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var fi = $("<textarea></textarea>").attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); fi.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(fi)); groupDiv.append(lbl).append(list); block.find(".wiktvi-dfn-nimune-group").before(groupDiv); fi.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { list.append(sec.steps.dfn.buildSenseBlock(stepDiv)); } sec.refresh(); }, onSubInput: steps.dfn.onSubInput, build: function (stepDiv) { if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(sec.steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, getSenses: steps.dfn.getSenses, getOutput: function (sv, callback) { var stepDiv = $(sel("dfn")); var senses = sec.steps.dfn.getSenses(stepDiv); var lang = sv.lang; var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } var dfn = sense.mane; if (!dfn) return undefined; if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var lp = sense.etiket.map(function (p) { return escapeTemplateParam($.trim(p)); }) .filter(function (p) { return p !== ""; }); if (lp.length) labelTpl = " {{e|" + lang + "|" + lp.join("|") + "}} "; } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; out += formatNimune(sense.nimune, lang); function wl(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wl("herwiha-rêz", sense.herwiha); out += wl("hevmane", sense.hevmane); out += wl("dijmane", sense.dijmane); out += wl("termên koordîne", sense.koordine); out += wl("jornav", sense.jornav); out += wl("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { callback(text); return; } var done = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", done, done); } }, je: secWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: secWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: secWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: sid("etym"), name: "etîmolojî", visible: function () { return false; }, output: function (sv) { return sv.lang === "ku" ? "==== Etîmolojî ====\n{{ji?|ku}}" : ""; } }, trans: { id: sid("trans"), name: "werger", visible: function (sv) { if (!(sv.lang === "ku" && sv[sid("pos")])) return false; var hasTpl = false; $(sel("dfn") + " li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTpl = true; return false; } }); return !hasTpl; }, disabledKeys: { "navz": true, "ku": true }, buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, sec.steps.trans.keys || [], sec.steps.trans.disabledKeys); langSel.on("change", function () { sec.steps.trans.onLangChange(stepDiv, row); }); var wordList = $("<ul class='wiktvi-trans-words'></ul>"); wordList.append($("<li></li>").append(sec.steps.trans.makeWordInput())); if (isMobile) row.append(wrapNativeSelect(langSel)).append(wordList); else row.append(langSel).append(wordList); return row; }, makeWordInput: steps.trans.makeWordInput, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); if (row.is(list.children("li.wiktvi-trans-row:last-child"))) { var nr = sec.steps.trans.buildRow(stepDiv); list.append(nr); if (!isMobile) nr.find("select").chosen(chosenOptions); } sec.steps.trans.syncDisabledKeys(stepDiv); }, syncDisabledKeys: steps.trans.syncDisabledKeys, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(sec.steps.trans.buildRow(stepDiv)); stepDiv.append(list); if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, getTranslations: steps.trans.getTranslations, output: function (sv) { if (sv.lang !== "ku") return ""; var stepDiv = $(sel("trans")); var rows = steps.trans.getTranslations(stepDiv); var out = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { rows.sort(function (a, b) { return (langsByCode[a[0]] && langsByCode[a[0]][2] || "") .localeCompare((langsByCode[b[0]] && langsByCode[b[0]][2] || ""), "ku"); }); out += "\n" + $.map(rows, function (row) { return "* {{Z|" + row[0] + "}}: " + row[1].map(escapeTemplateParam) .map(function (w) { return "{{W|" + row[0] + "|" + w + "}}"; }).join(", "); }).join("\n"); } out += "\n{{werger-bin}}\n\n"; return out; } } }; sec.steps.trans.keys = steps.trans.keys; sec.orderedSteps = [ sec.steps.pos, sec.steps.cinsiyet, sec.steps.lektur, sec.steps.tr, sec.steps.dfn, sec.steps.je, sec.steps.tekildar, sec.steps.binereherwiha, sec.steps.etym, sec.steps.trans ]; // Per-section getValues — merges shared lang into its own step values. sec.getValues = function () { var sv = $.extend({}, getSharedValues()); $.each(sec.steps, function (_, step) { var fields = $(sel(step.id.replace(suffix, "")) + " .wiktvi-start-step-field"); // For steps with a custom id already suffixed, use the full id DOM selector. fields = $("#" + "wiktvi-start-" + step.id + " .wiktvi-start-step-field"); if (step.keys) { var vals = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) vals[key] = $(field).val(); }); sv[step.id] = vals; } else if (step.multiple) { sv[step.id] = fields.map(function () { return $(this).val(); }).get(); } else { sv[step.id] = fields.val(); } }); return sv; }; // Per-section refresh — updates visibility and builds for this section's steps only. sec.refresh = function () { var sv = sec.getValues(); $(sel("dfn") + " .wiktvi-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); $.each(sec.steps, function (_, step) { var stepDiv = $("#wiktvi-start-" + step.id); if (typeof step.visible === "function" && !step.visible(sv)) { stepDiv.slideUp(); } else { if (typeof step.build === "function") { prepareInput(step.build(stepDiv, sv), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof step.example === "function") { input.attr("placeholder", step.example(sv) || ""); } stepDiv.slideDown(); } }); }; // Builds the section DOM block and appends it to the form. sec.buildDOM = function (startForm) { var wrapper = $("<div></div>") .addClass("wiktvi-pos-section") .attr("id", "wiktvi-pos-section" + suffix); var header = $("<div></div>").addClass("wiktvi-pos-section-header"); header.append("Beşa din — Cureyê rêzimanî"); var removeBtn = $("<button type='button'></button>") .addClass("wiktvi-remove-section").text("× Rake"); removeBtn.on("click", function () { wrapper.remove(); extraSections = $.grep(extraSections, function (s) { return s !== sec; }); }); header.append(removeBtn); wrapper.append(header); $.each(sec.orderedSteps, function (_, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) stepDiv.append(wrapNativeSelect(input)); else stepDiv.append(input); } else if (typeof step.build === "function") { input = step.build(stepDiv); } else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else { stepDiv.append(input); } } if (input) { if (step.required) input.prop("required", true); // On change, run this section's own refresh. input.on("change", function () { sec.refresh(); }); } stepDiv.hide(); wrapper.append(stepDiv); }); startForm.find("#wiktvi-start-footer").before(wrapper); if (!isMobile) wrapper.find("select.wiktvi-start-step-field").chosen(chosenOptions); // Listen to all input/change inside the section wrapper. wrapper.on("input change", function () { sec.refresh(); }); sec.refresh(); }; // Produces the wikitext for this section (chained async via callback). sec.getOutput = function (callback) { var sv = sec.getValues(); if (!sv[sid("pos")]) { callback(""); return; } var entry = sec.steps.pos.output(sv); sec.steps.dfn.getOutput(sv, function (dfnOut) { entry += dfnOut; entry += sec.steps.je.output(sv); entry += sec.steps.tekildar.output(sv); entry += sec.steps.binereherwiha.output(sv); entry += sec.steps.etym.output(sv); entry += sec.steps.trans.output(sv); callback(entry); }); }; return sec; } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function getWikitext(callback) { var values = getValues(); var entry = steps.lang.output(values); entry += steps.pron.output(values); entry += steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); // Chain extra sections sequentially then fire callback. function appendExtraSections(idx) { if (idx >= extraSections.length) { var senses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = senses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + values.lang + ":" + values.pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); return; } extraSections[idx].getOutput(function (secOut) { entry += secOut; appendExtraSections(idx + 1); }); } appendExtraSections(0); }); } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktvi-start-dfn .wiktvi-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); // Propagate lang change to all extra sections. $.each(extraSections, function (_, sec) { sec.refresh(); }); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktvi-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); startForm.append(stepDiv); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); var addSectionBtn = $(mw.html.element("button", { id: "wiktvi-add-section", type: "button" }, "+ Beşa din lê zêde bike")); addSectionBtn.css("margin-left", "6px"); addSectionBtn.on("click", function () { var suffix = "_s" + (extraSections.length + 2); var sec = createSection(suffix, getValues); extraSections.push(sec); sec.buildDOM(startForm); }); footer.append(addSectionBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 3lrlusio1cwzc291ssy9c4inx6dh9ht 6241601 6241600 2026-07-10T23:23:33Z Wikihez 7344 6241601 javascript text/javascript // Çavkanî [[vi:MediaWiki:Gadget-start.js]] //<nowiki> $(function () { var ns = mw.config.get("wgNamespaceNumber"); if (ns && !(ns === 2 && mw.config.get("wgPageName").match(/\/ceribandin$|\/test$/))) { return; } var action = mw.config.get("wgAction"); if (!(action === "edit" || action === "submit") || !$(".mw-newarticletext, .mw-newarticletextanon").length) { return; } if (window.location.href.includes("editintro=User:Wikihez/creation/intro")) { return; // Do not run the script wextê WF:Bilez dişuxile } // Hemû qutiyên nivîsê û textareayan di forma xebatê de dikarin // bi kaşkirina kuncê rastê yê jêr mezin an biçûk bibin. mw.util.addCSS( "#wiktvi-start-form textarea.wiktvi-start-step-field," + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield {" + " resize: both !important;" + " overflow: auto !important;" + " box-sizing: border-box !important;" + " vertical-align: top;" + "}" + "#wiktvi-start-form textarea.wiktvi-start-narrow," + "#wiktvi-start-form textarea.wiktvi-dfn-subfield.wiktvi-start-narrow {" + " width: 20em;" + " min-width: 8em;" + " height: calc(1em + 8px);" + " min-height: calc(1em + 8px);" + " padding-top: 2px !important;" + " padding-bottom: 2px !important;" + " line-height: 1.4 !important;" + "}" + ".wiktvi-native-select-wrap { display: inline-block; position: relative; }" + ".wiktvi-native-select-wrap input[type='search'] {" + " display: block;" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "ul.wiktvi-ac-results {" + " position: absolute;" + " z-index: 9999;" + " background: #fff;" + " border: 1px solid #a2a9b1;" + " margin: 0;" + " padding: 0;" + " list-style: none;" + " width: 20em;" + " max-width: 90vw;" + " max-height: 14em;" + " overflow-y: auto;" + " -webkit-overflow-scrolling: touch;" + "}" + "ul.wiktvi-ac-results li {" + " padding: 6px 10px;" + " cursor: pointer;" + " font-size: 0.95em;" + "}" + "ul.wiktvi-ac-results li:active {" + " background: #3366cc;" + " color: #fff;" + "}" + "#wiktvi-preview-panel {" + " margin-top: 1em;" + " padding: 0.8em;" + " background: #f8f9fa;" + " border: 1px solid #a2a9b1;" + " white-space: pre-wrap;" + " word-break: break-word;" + " font-family: monospace;" + " font-size: 0.9em;" + "}" + "a.wiktvi-dfn-label-toggle," + "a.wiktvi-dfn-lazy-toggle {" + " display: inline-block;" + " margin: 2px 4px 2px 0;" + " font-size: 0.85em;" + "}" + ".wiktvi-dfn-lazy-links {" + " margin: 2px 0 4px;" + " line-height: 1.8;" + "}" + ".wiktvi-dfn-tpl-row {" + " margin-bottom: 4px;" + "}" + ".wiktvi-dfn-tpl-select {" + " font-size: 0.9em;" + "}" + "input.wiktvi-dfn-tpl-title {" + " width: 20em;" + " max-width: 100%;" + " box-sizing: border-box;" + "}" + "#wiktvi-section-tabs {" + " display: flex;" + " flex-wrap: wrap;" + " gap: 4px;" + " margin-bottom: 0.6em;" + "}" + "#wiktvi-section-tabs .wiktvi-section-tab {" + " padding: 3px 10px;" + " border: 1px solid #a2a9b1;" + " border-radius: 3px 3px 0 0;" + " background: #eaecf0;" + " cursor: pointer;" + " font-size: 0.9em;" + " user-select: none;" + "}" + "#wiktvi-section-tabs .wiktvi-section-tab.wiktvi-tab-active {" + " background: #fff;" + " border-bottom-color: #fff;" + " font-weight: bold;" + "}" ); // Herfa ewil a kelîmeyê dike mezin. Fonksiyoneke sade li şûna // String.prototype.wiktviCapitalize, daku prototypeya bingehîn neyê // gemarîkirin, û bi ewletir e (rasterast li ser rêzikên vala kar dike). function capitalize(str) { if (!str) return str; return str[0].toUpperCase() + str.substr(1); } // Karakterên xisûsî ên RegExp-ê direvîne, daku nivîsa dînamîk (wek navê // rûpelê) bi ewletî bikeve nav `new RegExp(...)`. function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } // Karakterên ku maneyeke xisûsî di parametreyên şablonan de hene ("|" ji // hev cuda dike, "=" dibe ku wek nav=nirx were şirovekirin) direvîne, // daku nivîsa vekirî ya bikarhêner şablonê neşikîne. function escapeTemplateParam(str) { if (typeof str !== "string") return str; return str.replace(/\|/g, "{{!}}").replace(/=/g, "{{=}}"); } var pageName = mw.config.get("wgPageName").replace(/_/g, " "); if (ns) pageName = pageName.replace(/.*\//, ""); var pageNameRe = escapeRegExp(pageName); var userLang = mw.config.get("wgUserLanguage"); // Mobile detection: MobileFrontend sets wgMFMode, or fall back to touch check. var isMobile = !!mw.config.get("wgMFMode") || window.matchMedia("(pointer: coarse)").matches; var chosenOptions = { width: "20em", disable_search_threshold: 0, placeholder_text_single: "Yek hilbijêre", placeholder_text_multiple: "Hilbijêre", no_results_text: "Nehat dîtin", enable_split_word_search: true, search_contains: true }; /** * On mobile, replaces chosen with a single-box autocomplete widget. * The user sees one <input>; typing filters a results list below it. * Selecting a result sets the hidden <select> value and fires "change" * so the rest of the form reacts normally. * * The original <select> is kept hidden so all existing .val() / change * bindings continue to work unchanged. */ function wrapNativeSelect(select) { var placeholder = select.attr("data-placeholder") || "Lê bigere…"; // Hide the native select — we drive it programmatically. select.hide(); var wrapper = $("<span class='wiktvi-native-select-wrap'></span>"); var textInput = $("<input type='search' autocomplete='off'>") .attr("placeholder", placeholder) .addClass("wiktvi-start-narrow wiktvi-ac-input"); var resultsList = $("<ul class='wiktvi-ac-results'></ul>").hide(); // Full option cache — rebuilt when chosen:updated fires. var allOptions = []; function cacheOptions() { allOptions = []; select.find("option").each(function () { var v = $(this).val(); if (!v) return; // skip the empty placeholder option allOptions.push({ value: v, text: $(this).text(), disabled: $(this).prop("disabled") }); }); } cacheOptions(); function showResults(query) { var q = query.trim().toLowerCase(); resultsList.empty(); var matched = q ? $.grep(allOptions, function (o) { return !o.disabled && o.text.toLowerCase().indexOf(q) !== -1; }) : allOptions.filter(function (o) { return !o.disabled; }); if (!matched.length) { resultsList.hide(); return; } $.each(matched.slice(0, 50), function (_, opt) { var li = $("<li></li>").text(opt.text).attr("data-value", opt.value); li.on("mousedown touchstart", function (e) { // Use mousedown/touchstart (before blur) to register the pick. e.preventDefault(); selectOption(opt.value, opt.text); }); resultsList.append(li); }); resultsList.show(); } function selectOption(value, text) { textInput.val(text); select.val(value); resultsList.hide(); select.trigger("change"); } textInput.on("input focus", function () { showResults($(this).val()); }); textInput.on("blur", function () { // Short delay so a touchstart on a result item fires first. setTimeout(function () { resultsList.hide(); }, 200); }); // chosen:updated → re-cache (called after ziman.json loads). select.on("chosen:updated", function () { cacheOptions(); // If a value is already selected, keep the display text in sync. var cur = select.val(); if (cur) { var match = $.grep(allOptions, function (o) { return o.value === cur; })[0]; if (match) textInput.val(match.text); } }); // No-op .chosen() so desktop call-sites don't need guarding. select.chosen = function () { return select; }; wrapper.append(textInput).append(resultsList).append(select); return wrapper; } var langsByCode = {}; var metadata={aa:{haswikt:1,sc:["Latn","Ethi"]},ab:{haswikt:1,sc:["Cyrl","Latn","Geor"]},aer:{sc:"Latn"},af:{g:["y","p"],haswikt:1},ak:{haswikt:1},akk:{g:["n","m","n-p","m-p"],sc:"Xsux"},als:{haswikt:1},am:{g:["n","m","n-p","m-p"],haswikt:1,sc:"Ethi"},an:{g:["n","m","n-p","m-p"],haswikt:1},ang:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},ar:{g:["n","m","n-p","m-p","p"],alt:1,haswikt:1,sc:"Arab"},arc:{g:["n","m","n-p","m-p"],sc:["Hebr","Syrc"]},are:{},arz:{alt:1,g:["n","m","n-p","m-p"],sc:"Arab"},as:{haswikt:1,sc:"Beng"},ast:{g:["n","m","n-p","m-p"],haswikt:1},av:{haswikt:1},ay:{haswikt:1},az:{g:["y","p"],haswikt:1,sc:["Latn","Cyrl","Arab"]},ba:{g:["y","p"],sc:"Cyrl"},bar:{},"bat-smg":{g:["n","m","n-p","m-p"]},bbl:{sc:"Geor"},be:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},"be-x-old":{sc:"Cyrl"},bg:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},bh:{haswikt:1,sc:"Deva"},bhb:{sc:"Deva"},bi:{haswikt:1},blt:{sc:"Tavt"},bm:{haswikt:1,sc:["Latn","Nkoo","Arab"]},bn:{haswikt:1,sc:"Beng"},bo:{haswikt:1,sc:"Tibt"},br:{g:["n","m"],haswikt:1},ca:{g:["n","m","n-p","m-p"],haswikt:1},cdo:{sc:"Hani"},ce:{sc:"Cyrl"},ch:{haswikt:1},chr:{haswikt:1,sc:"Cher"},cjy:{sc:"Hani"},ckb:{haswikt:1,sc:"Arab",wsc:"ku-Arab"},cmn:{sc:"Hani",wiktprefix:"zh"},co:{haswikt:1},cpx:{sc:"Hani"},cr:{haswikt:1,sc:"Cans"},crh:{},cs:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},csb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},cu:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:["Cyrs","Glag"]},cv:{sc:"Cyrl"},cy:{g:["n","m","n-p","m-p"],haswikt:1},czh:{sc:"Hani"},czo:{sc:"Hani"},da:{g:["g","nt","g-p","nt-p","p"],haswikt:1},dax:{},de:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,allowCaps:1},dhg:{},djb:{},dji:{},djr:{},dng:{sc:"Cyrl"},dsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},dsx:{},duj:{},dv:{g:["y","p"],haswikt:1,sc:"Thaa"},dz:{haswikt:1,sc:"Tibt"},el:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},en:{g:["y","p"],haswikt:1},eo:{g:["y","p"],haswikt:1},es:{g:["n","m","n-p","m-p","p"],haswikt:1},et:{g:["y","p"],haswikt:1},ett:{g:["y","p"],sc:"Ital"},eu:{g:["y","p"],haswikt:1},fa:{haswikt:1,g:["y","p"],sc:"Arab",wsc:"fa-Arab"},"fa-cls":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},"fa-ira":{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},fi:{g:["y","p"],haswikt:1},fil:{},fj:{haswikt:1},fo:{g:["n","m","nt"],haswikt:1},fr:{g:["n","m", "mnmane", "n-p","m-p","p"],haswikt:1},frm:{g:["n","m","n-p","m-p"]},fro:{g:["n","m","n-p","m-p"]},fur:{g:["n","m","n-p","m-p"]},fy:{g:["g","nt","p"],haswikt:1},ga:{g:["n","m","n-p","m-p","p"],haswikt:1},gan:{sc:"Hani"},gd:{g:["n","m","n-p","m-p"],haswikt:1},gez:{sc:"Ethi"},gl:{g:["n","m","n-p","m-p"],haswikt:1},"gmw-ecg":{g:["n","m","nt","p"],allowCaps:1},gmy:{sc:"Linb"},gn:{haswikt:1},gnn:{sc:"Latn"},got:{g:["n","m","nt","n-p","m-p","nt-p"],sc:"Goth"},grc:{g:["n","m","nt","n-p","m-p","nt-p","p"]},gsw:{g:["n","m","nt","p"],allowCaps:1},gu:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Gujr"},guf:{sc:"Latn"},gv:{haswikt:1},ha:{haswikt:1},hak:{sc:"Hani"},har:{sc:"Ethi"},he:{alt:1,g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Hebr"},hi:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Deva"},hif:{sc:["Latn","Deva"]},hit:{sc:"Xsux"},hrx:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},hsb:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},hsn:{sc:"Hani"},hu:{g:["y","p"],haswikt:1},hy:{g:["y","p"],haswikt:1,sc:"Armn"},ia:{haswikt:1},id:{haswikt:1},ie:{haswikt:1},ik:{haswikt:1},ike:{sc:"Cans"},ikt:{sc:"Cans"},io:{haswikt:1},is:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},it:{g:["n","m","n-p","m-p","p"],haswikt:1},iu:{haswikt:1,sc:"Cans"},ja:{haswikt:1,sc:"Jpan"},jay:{sc:"Latn"},jbo:{haswikt:1},jv:{haswikt:1},ka:{g:["y","p"],haswikt:1},khb:{sc:["Talu","Lana","Thai"]},kjh:{sc:"Cyrl"},kk:{haswikt:1,g:["y","p"],sc:"Cyrl"},kkh:{sc:["Lana","Thai"]},kl:{haswikt:1},km:{haswikt:1,sc:"Khmr"},kn:{haswikt:1,sc:"Knda"},ku:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"ku"},ko:{haswikt:1,sc:"Kore"},krc:{g:["y","p"],sc:"Cyrl"},ks:{haswikt:1,sc:["Arab","Deva"],wsc:"ks-Arab"},kw:{haswikt:1},ky:{haswikt:1,g:["y","p"],sc:"Cyrl"},la:{alt:1,g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},lb:{g:["n","m","nt","p"],haswikt:1,allowCaps:1},lez:{sc:"Cyrl"},li:{haswikt:1},lki:{wiktprefix:"ku"},lld:{g:["n","m","n-p","m-p"],haswikt:1},lmo:{g:["n","m","n-p","m-p"],haswikt:1},ln:{haswikt:1},lo:{haswikt:1,sc:"Laoo"},lt:{alt:1,g:["n","m","n-p","m-p"],haswikt:1},lv:{g:["n","m","n-p","m-p"],haswikt:1},lzz:{sc:"Geor"},mg:{haswikt:1},mh:{haswikt:1},mi:{g:0,haswikt:1},mk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ml:{haswikt:1,sc:"Mlym"},mn:{g:["y","p"],haswikt:1,sc:["Cyrl","Mong"]},mnp:{sc:"Hani"},mo:{haswikt:1,sc:"Cyrl"},mol:{sc:"Cyrl"},mr:{g:["n","m","nt"],haswikt:1,sc:"Deva"},ms:{haswikt:1,sc:["Latn","Arab"]},mt:{g:["n","m","n-p","m-p","p"],haswikt:1},mwp:{sc:"Latn"},my:{haswikt:1,sc:"Mymr"},na:{haswikt:1},nah:{haswikt:1},nan:{wiktprefix:"zh-min-nan",sc:"Hani"},nb:{g:["n","m","nt","n-p","m-p","nt-p","p"],wiktprefix:"no"},"nds-de":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},"nds-nl":{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},ne:{haswikt:1,sc:"Deva"},nl:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nn:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},no:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1},nod:{sc:"Lana"},non:{g:["n","m","nt","n-p","m-p","nt-p"]},oc:{g:["n","m","n-p","m-p"],haswikt:1},om:{haswikt:1},or:{haswikt:1,sc:"Orya"},orv:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrs"},osc:{sc:"Ital"},ota:{g:["y","p"],sc:"Arab",wsc:"ota-Arab"},pa:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:["Guru","Arab"]},pdt:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"nds"},peo:{sc:"Xpeo"},phn:{sc:"Phnx"},pi:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1},pjt:{sc:"Latn"},pl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},pms:{g:["n","m","n-p","m-p"],haswikt:1},pox:{g:["n","m","nt","n-p","m-p","nt-p","împf","pf"]},prs:{wiktprefix:"fa",sc:"Arab",wsc:"fa-Arab"},ps:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ps-Arab"},pt:{g:["n","m","n-p","m-p","p"],haswikt:1},qu:{haswikt:1},rgn:{g:["n","m","n-p","m-p"]},rit:{sc:"Latn"},rm:{g:["n","m"],haswikt:1},rn:{haswikt:1},ro:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:["Latn","Cyrl"]},"roa-rup":{haswikt:1},ru:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},rue:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],sc:"Cyrl"},ruo:{g:["n","m","nt","n-p","m-p","nt-p"]},rup:{g:["n","m","nt","n-p","m-p","nt-p"],wiktprefix:"roa-rup"},ruq:{g:["n","m","nt","n-p","m-p","nt-p"]},rw:{haswikt:1},sa:{g:["n","m","nt","n-p","m-p","nt-p"],haswikt:1,sc:"Deva"},sah:{sc:"Cyrl"},sc:{haswikt:1},scn:{g:["n","m","n-p","m-p"],haswikt:1},sco:{sc:"Latn"},sd:{haswikt:1,sc:"Arab",wsc:"sd-Arab"},sdh:{wiktprefix:"ku"},sg:{haswikt:1},sh:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:["Latn","Cyrl"]},si:{haswikt:1,sc:"Sinh"},simple:{haswikt:1},sk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sl:{alt:1,g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1},sm:{haswikt:1},sn:{haswikt:1},so:{haswikt:1},spx:{sc:"Ital"},sq:{g:["n","m"],haswikt:1},ss:{haswikt:1},st:{haswikt:1},su:{haswikt:1},sux:{sc:"Xsux"},sv:{g:["g","nt","g-p","nt-p"],haswikt:1},sva:{sc:"Geor"},sw:{nclass:1,haswikt:1},syc:{sc:"Syrc"},syr:{sc:"Syrc"},szl:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"]},ta:{haswikt:1,sc:"Taml"},tdd:{sc:"Tale"},te:{haswikt:1,sc:"Telu"},tg:{g:["y","p"],haswikt:1,sc:"Cyrl"},th:{haswikt:1,sc:"Thai"},ti:{haswikt:1,sc:"Ethi"},tig:{sc:"Ethi"},tiw:{sc:"Latn"},tk:{g:["y","p"],haswikt:1},tl:{haswikt:1,sc:["Latn","Tglg"]},tmr:{sc:"Hebr"},tn:{haswikt:1},to:{haswikt:1},tpi:{haswikt:1},tr:{g:["y","p"],alt:1,haswikt:1},ts:{haswikt:1},tt:{g:["y","p"],haswikt:1},tts:{sc:"Thai"},tw:{haswikt:1},udi:{sc:["Cyrl","Latn","Armn","Geor"]},ug:{g:["y","p"],haswikt:1,sc:"Arab",wsc:"ug-Arab"},uga:{sc:"Ugar"},uk:{g:["n","m","nt","n-p","m-p","nt-p","p","împf","pf"],haswikt:1,sc:"Cyrl"},ulk:{sc:"Latn"},ur:{g:["n","m","n-p","m-p","p"],haswikt:1,sc:"Arab",wsc:"ur-Arab"},uz:{g:["y","p"],haswikt:1},vec:{g:["n","m","n-p","m-p"],haswikt:1},vi:{haswikt:1},vls:{g:["n","m","nt","n-p","m-p","nt-p"]},vo:{haswikt:1},wa:{haswikt:1},wbp:{sc:"Latn"},wo:{haswikt:1},wuu:{sc:"Hani"},xae:{sc:"Ital"},xcr:{sc:"Cari"},xfa:{sc:"Ital"},xh:{alt:1,nclass:1,haswikt:1},xlc:{sc:"Lyci"},xld:{sc:"Lydi"},xlu:{sc:"Xsux"},xmf:{sc:"Geor"},xno:{g:["n","m","n-p","m-p"]},xrr:{sc:"Ital"},xst:{sc:"Ethi"},xum:{sc:"Ital"},xve:{sc:"Ital"},xvo:{sc:"Ital"},yi:{g:["n","m","nt","n-p","m-p","nt-p","p"],haswikt:1,sc:"Hebr"},yo:{haswikt:1},yua:{g:["y","p"],alt:1},yue:{sc:"Hani"},za:{haswikt:1,sc:"Latn"},"zh-classical":{sc:"Hani"},"zh-min-nan":{haswikt:1},"zh-yue":{sc:"Hani"},zu:{alt:1,nclass:1,haswikt:1}}; function needsTransliteration(langCode) { var meta = metadata[langCode]; if (!meta || !meta.sc) return false; var scripts = Array.isArray(meta.sc) ? meta.sc : [meta.sc]; return scripts.length > 0 && scripts[0] !== "Latn"; } // Kodên cinsiyetê yên di metadata.g de (li gorî peymana vê skrîptê: // m = mê, n = nêr, nt = nêtar, mn/c = mê û nêr) bo etîketên kurmancî. var GENDER_BASE_LABELS = { m: "mê", n: "nêr", nt: "nêtar", mn: "mê û nêr", c: "giştî" }; /** * Kodeke cinsiyetê (wek "m", "n-p", "p") vediguherîne etîketeke * kurmancî ya xwendinbar. Kodên "-p" forma pirjimar a wê cinsiyetê * nîşan didin. Kodên nenas (wek yên taybet ên hin zimanan) bi kodê * xwe re têne nîşandan, ne bi texmînek çewt. */ function genderLabel(code) { if (code === "p") return "Pirjimar"; var pluralMatch = code.match(/^(.+)-p$/); if (pluralMatch && GENDER_BASE_LABELS[pluralMatch[1]]) { return GENDER_BASE_LABELS[pluralMatch[1]] + " (pirjimar)"; } return GENDER_BASE_LABELS[code] || code; } /** * Rêzeke nimûneyan (ku berê hatine paqijkirin bi $.trim) vediguherîne * beşa wikînivîsê ya di bin tarîfekê de: an rêzikên "#: {{nm|...}}" * bo her nimûneyekê, an "#* {{bênimûne|lang}}" ger ti nimûne tinebe. * Vê mantiqê carekê tenê hebe — di kodê ya berê de du caran hatibû * nivîsandin (bo dema tarîf heye û ne vala ye). */ function formatNimune(nimunes, lang) { var hasNimune = nimunes && $.grep(nimunes, function (nimune) { return nimune !== ""; }).length > 0; if (!hasNimune) { return "\n#* {{bênimûne|" + lang + "}}"; } return $.map(nimunes, function (nimune) { if (nimune === "") return undefined; var bolded = nimune.replace( new RegExp("(" + pageNameRe + "([^( |,|;|\\?|\\.|\\!)]+)?)", "ig"), "'''$1'''"); return "\n#: {{nm|" + lang + "|" + escapeTemplateParam(bolded) + "}}"; }).join(""); } /** * Fabrîkeyek bo gavên "lîsteya kelîmeyan" ên hevşibin: jê, têkildar, binêre herwiha. Berê pênc caran bi hemû wek hev dihatin * nivîsandin; niha cudahiya wan tenê nav, pirs û sernivîsa wan e. */ function makeWordListStep(id, name, question_fmt, header, templateName) { return { id: id, name: name, question_fmt: question_fmt, multiple: true, narrow: true, visible: function (values) { return values.lang && values.pos; }, output: function (values) { var words = values[id]; if (!words.join("").length) return ""; return "==== " + header + " ====\n" + $.map(words, function (word) { return word ? "* {{" + templateName + "|" + values.lang + "|" + escapeTemplateParam(word) + "}}" : undefined; }).join("\n") + "\n\n"; } }; } var steps = { lang: { id: "lang", required: true, name: "ziman", question_fmt: "“{{PAGENAME}}” bi çi zimanî ye?", question_br: true, choices: [ // Languages with 100 or more entries are loaded immediately. // The rest come in through [[MediaWiki:Gadget-translation_editor.js/ziman.json]]. ["ku", "kurmancî"], ["zza", "zazakî"], ["ckb", "soranî"], ["sdh", "kurdiya başûrî"], ["de", "almanî"], ["ar", "erebî"], ["fa", "farisî"], ["fr", "fransî"], ["fi", "fînî"], ["en", "îngilîzî"], ["sv", "swêdî"], ["tr", "tirkî"] ], output: function (values) { return "== {{ziman|" + values.lang + "}} ==\n\n"; } }, pron: { id: "pron", name: "bilêvkirin", question_fmt: "“{{PAGENAME}}” çawa tê telafûzkirin?", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "=== Bilêvkirin ===\n* {{ku-kîte}}\n\n"; } return ""; } }, pos: { id: "pos", required: true, name: "Cureyê rêzimanî", question_fmt: "Cureyê rêzimanî yê “{{PAGENAME}}” çi ye?", visible: function (values) { return values.lang; }, question_br: true, choices: [ ["navdêr", "Navdêr (îsm)"], ["lêker", "Lêker (fiîl)"], ["rengdêr", "Rengdêr (sifet)"], ["hoker", "Hoker (zerf)"], ["serenav", "Serenav (îsmê xisûsî)"], ["artîkel", "Artîkel"], ["baneşan", "Baneşan (nîda)"], ["bazinedaçik", "Bazinedaçek"], ["cînav", "Cînav (zemîr)"], ["daçek", "Daçek (edat)"], ["girêdek", "Girêdek"], ["gotineke pêşiyan","Gotineke pêşiyan"], ["hejmar", "Hejmar"], ["hevok", "Hevok (cimle)"], ["îfade", "Îfade"], ["kurtenav", "Kurtenav"], ["navgir", "Navgir"], ["paşdaçek", "Paşdaçek"], ["paşgir", "Paşgir"], ["pêşdaçek", "Pêşdaçek"], ["pêşgir", "Pêşgir"], ["pirtik", "Pirtik"], ["reh", "Reh"], ["sembol", "Sembol"], ["tîp", "Tîp (herf)"] ], output: function (values) { var pos = values.pos || ""; var cinsiyet = values.cinsiyet || ""; // from the cinsiyet step var lekTur = values.lektur || ""; // from the lêker transitivity step var capitalizedPos = capitalize(pos); var outputString = "=== " + capitalizedPos + " ===\n"; // Gender-to-Kurmancî name map (used by ku-tewîn-nav). // "nt" tê de nîne bi qesd — ne bi "mn" tê wekhevkirin (li gorî // biryara berê), loma ji bo "nt" şablona ku-tewîn-nav nayê zêdekirin. var genderNames = { m: "mê", n: "nêr", mn: "mê û nêr" }; // Add ku-tewîn-nav for single-word navdêr/serenav with known gender. if (!pageName.includes(" ") && cinsiyet && genderNames[cinsiyet] && (pos === "navdêr" || pos === "serenav") && values.lang === "ku") { outputString += "{{ku-tewîn-nav|" + pageName + "|" + genderNames[cinsiyet] + "}}\n"; } outputString += "{{" + pos + "|" + values.lang; if (pos === "navdêr" || pos === "serenav") { if (cinsiyet) { outputString += "|c=" + cinsiyet; } else if (values.lang === "ku") { // Unknown gender — prompt editor to fill it in. outputString += "|c=?"; } } else if (/^lêker/.test(pos) && lekTur) { outputString += "|c=" + lekTur; } if (values.tr) { outputString += "|tr=" + escapeTemplateParam(values.tr); } outputString += "}}\n"; return outputString; } }, /** * cinsiyet (grammatical gender) — only shown for navdêr/serenav, û * tenê ger metadata ji bo zimanê hilbijartî lîsteyeke "g" (cinsiyet) * were dayîn. Bijardeyên vê gavê ne sabît in — ji metadata[values.lang].g * têne çêkirin, ji ber ku ne hemû ziman heman cinsiyetan hene (an qet * cinsiyet nînin). */ cinsiyet: { id: "cinsiyet", name: "cinsiyet", question_fmt: "Cinsiyeta kelîmeyê çi ye?", question_br: true, visible: function (values) { var meta = metadata[values.lang]; return !!(values.lang && (values.pos === "navdêr" || values.pos === "serenav") && meta && meta.g && meta.g.length); }, build: function (stepDiv, values) { var select = stepDiv.find("select.wiktvi-start-step-field"); if (!select.length) { select = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-cinsiyet-field" })); stepDiv.append(select); } // Gava yekem (ji build()-a giştî) values nayê şandin — hîna // ziman nehatiye hilbijartin, ji ber vê tenê select-a vala // vegerîne, dê bi refresh() were dagirtin. if (!values) return select; var meta = metadata[values.lang]; var codes = (meta && meta.g) || []; var prevVal = select.val(); var choices = $.map(codes, function (code) { return [[code, genderLabel(code)]]; }); populateMenus(select, choices); if ($.grep(choices, function (c) { return c[0] === prevVal; }).length) { select.val(prevVal); } if (!isMobile) select.trigger("chosen:updated"); return select; }, output: function () { return ""; } // consumed by pos.output }, /** * Lêker transitivity — only shown for any lêker variant. * Add new transitivity values to the choices dict here. */ lektur: { id: "lektur", name: "Cureyê lêkerê", question_fmt: "Cureyê lêkerê çi ye?", question_br: true, visible: function (values) { return values.lang && values.pos && /^lêker/.test(values.pos); }, // Dictionary: value → display label. Add new types here. choices: [ ["gh", "Gerguhêz"], ['x-gh', 'Xwerû-gerguhêz'], ['p-gh', 'pêkhatî-gerguhêz'], ['h-gh', 'hevedudanî-gerguhêz'], ['b-gh', 'biwêjî-gerguhêz'], ["ngh", "Negerguhêz"], ['x-ngh', 'xwerû-negerguhêz'], ['p-ngh', 'pêkhatî-negerguhêz'], ['h-ngh', 'hevedudanî-negerguhêz'], ['b-ngh', 'biwêjî-negerguhêz'] ], output: function () { return ""; } // consumed by pos.output }, tr: { id: "tr", name: "transkrîpsiyon", question_fmt: "Transkrîpsiyona kelîmeyê", multiple: false, narrow: true, visible: function (values) { return values.lang && values.pos && needsTransliteration(values.lang); } }, dfn: { id: "dfn", // required: true, ger mane tinebe [[Şablon:mane?]] bi kar bîne name: "Mane", question_fmt: "Mane û nimûneyên kelîmeyê binivîse. Ji bo tercimeyan beşa 'Werger' bi kar bîne!", multiple: true, ordered: true, rows: 3, visible: function (values) { return values.lang && values.pos; }, example: function (values) { var examples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var transExamples = { "navdêr": "Kelîmeyên ji bo tiştan (sêv, heywan, qedeh) yan terman (dilşadî, bextiyarî hwd.) di rêzimanê de.", "lêker": "Kelîmeyên ji bo kirin an bûyînê wekî 'nivîsîn' yan 'xeber dan'.", "rengdêr": "Kelîmeyên ku wesfa navdêran nîşan didin wekî 'sêva sor' yan 'xwarina şîrîn'.", "hoker": "Kelîmeyên ku dem, cih yan awayê kirinê diyar dikin wekî 'bi vî awayî' yan 'demkî'.", "daçek": "Kelîmeyên ku cih, dem yan hereketê diyar dikin wekî 'di.. de' yan 'ji'.", "cînav": "Kelîmeyên ku li şûna navdêran tên bikaranîn daku navdêr neyên dubarekirin wekî 'ew' yan 'em'.", "baneşan": "Kelîmeyên ku hest, deng hwd. îfade diin wekî 'noşî!' yan 'aferîn'.", "serenav": "Navdêrên ku şexsiyetên ferdî nîşan didin, wek navên kes, cih an organîzasyonan nimûne 'London' yan 'Diyarbekir'.", "gotineke pêşiyan": "Gotinên ku di nav xelkê de bi berbelavî tên bikaranîn bo nimûne 'Serê neêşe ne hewceyî destmalê ye'." }; var pos = values.pos ? values.pos.split("/")[0] : ""; return values.lang === "ku" ? (examples[pos] || "") : (transExamples[pos] || ""); }, /** * Builds one sense block (<li>) inside the ordered list. * Each block contains: * - a textarea for the definition * - an expandable nimûne list * - single-row sub-lists for herwiha, hevmane, dijmane */ buildSenseBlock: function (stepDiv) { var block = $("<li class='wiktvi-dfn-sense'></li>"); // — Mane textarea (declared first so the template handler can reference it) — var dfnArea = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field wiktvi-dfn-mane") .attr("rows", 3) .attr("placeholder", "Mane…"); dfnArea.on("input", function () { steps.dfn.onDfnInput(stepDiv, block, this); }); // — Template selector (optional — replaces mane when chosen) — // langs: null = all languages, otherwise array of allowed lang codes. var tplDefs = [ { name: "Guharto", langs: null }, { name: "Hevmaneya", langs: null }, { name: "Awayekî din", langs: null }, { name: "Pirjimar", langs: null }, { name: "Romanization", langs: null }, { name: "Awayê Jacobsonê", langs: ["zza"] }, { name: "ku-Latn", langs: ["ku"] }, { name: "ku-Arab", langs: ["ku"] }, { name: "ckb-Latn", langs: ["ckb"] }, { name: "ckb-Arab", langs: ["ckb"] } ]; var tplSelect = $(mw.html.element("select", { "class": "wiktvi-dfn-tpl-select" })); tplSelect.append($("<option value=''>— an şablonek hilbijêre —</option>")); $.each(tplDefs, function (_, tpl) { tplSelect.append( $("<option></option>") .val(tpl.name) .text(tpl.name) .attr("data-langs", tpl.langs ? tpl.langs.join(",") : "") ); }); // Shows only options valid for the current lang; resets selection if // the currently chosen template is no longer valid. function updateTplOptions() { var lang = getValues().lang || ""; var currentVal = tplSelect.val(); var currentStillValid = false; tplSelect.find("option[value!='']").each(function () { var allowed = $(this).attr("data-langs"); var visible = !allowed || allowed.split(",").indexOf(lang) !== -1; $(this).toggle(visible); if ($(this).val() === currentVal && visible) currentStillValid = true; }); if (currentVal && !currentStillValid) { tplSelect.val(""); dfnArea.show(); tplTitleInput.hide().val(""); } } // Store updater on the element so refresh() can call it for all blocks. tplSelect.data("updateOptions", updateTplOptions); var tplTitleInput = $("<input type='text'>") .addClass("wiktvi-dfn-tpl-title wiktvi-start-narrow") .attr("placeholder", "Navê rûpelê…") .hide(); tplSelect.on("change", function () { var chosen = $(this).val(); if (chosen) { dfnArea.hide(); tplTitleInput.show().focus(); } else { dfnArea.show(); tplTitleInput.hide().val(""); } // Re-run refresh so the Werger step visibility updates. refresh(); }); var tplRow = $("<div></div>").addClass("wiktvi-dfn-tpl-row") .append(tplSelect).append(" ").append(tplTitleInput); block.append(tplRow); block.append(dfnArea); // Apply lang filter on initial build. updateTplOptions(); // — Inline links row: (+ Etîket) + all lazy sub-group triggers — // Sits right before the Nimûne textarea; all lazy fields are revealed by clicking their link. var lazyLinksDiv = $("<div></div>").addClass("wiktvi-dfn-lazy-links"); block.append(lazyLinksDiv); // — Sub-field groups — // nimûne: always visible (inserted after the links row). // etîket + herwiha/hevmane/dijmane/koordine/jornav/jernav: lazy (click-to-add). var allGroups = [ { cls: "wiktvi-dfn-etiket", label: "Etîket", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-nimune", label: "Nimûne", rows: 2, narrow: false, lazy: false }, { cls: "wiktvi-dfn-herwiha", label: "Herwiha", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-hevmane", label: "Hevmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-dijmane", label: "Dijmane", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-koordine", label: "Termên koordîne", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jornav", label: "Jornav", rows: 1, narrow: true, lazy: true }, { cls: "wiktvi-dfn-jernav", label: "Jêrnav", rows: 1, narrow: true, lazy: true } ]; $.each(allGroups, function (_, g) { var groupDiv = $("<div></div>").addClass("wiktvi-dfn-subgroup " + g.cls + "-group"); if (!g.lazy) { // Always-visible group (Nimûne) — appended after the links row. var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield" + (g.narrow ? " wiktvi-start-narrow" : "")); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, g.narrow); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); block.append(groupDiv); } else { // Lazy group — link lives in lazyLinksDiv; group is built on click. var addLink = $("<a href='#'></a>") .addClass("wiktvi-dfn-lazy-toggle") .text("(+ " + g.label + ")"); addLink.on("click", function (evt) { evt.preventDefault(); addLink.remove(); var lbl = $("<span></span>").addClass("wiktvi-dfn-sublabel").text(g.label + ": "); var list = $("<ol></ol>").addClass("wiktvi-dfn-sublist " + g.cls + "-list"); var firstInput = $("<textarea></textarea>") .attr("rows", g.rows) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow"); firstInput.on("input", function () { steps.dfn.onSubInput(list, this, g.rows, true); }); list.append($("<li></li>").append(firstInput)); groupDiv.append(lbl).append(list); // Insert before Nimûne (the last fixed group) to preserve declaration order. block.find(".wiktvi-dfn-nimune-group").before(groupDiv); firstInput.focus(); }); lazyLinksDiv.append(addLink).append(" "); } }); return block; }, /** Grows the sense list when the last mane textarea gets content. */ onDfnInput: function (stepDiv, block, textarea) { var val = $.trim($(textarea).val()); var list = stepDiv.find("ol.wiktvi-dfn-list"); var isLast = block.is(list.children("li:last-child")); if (val && isLast) { var newBlock = steps.dfn.buildSenseBlock(stepDiv); list.append(newBlock); } refresh(); }, /** Grows a sub-list (nimûne/herwiha/hevmane/dijmane/termên koordîne) on input. */ onSubInput: function (list, input, rows, narrow) { var val = $.trim($(input).val()); var item = $(input).parent(); var isLast = item.is(list.children("li:last-child")); if (val && isLast) { var next = $("<textarea></textarea>") .attr("rows", rows) .attr("class", "wiktvi-dfn-subfield" + (narrow ? " wiktvi-start-narrow" : "")); next.on("input", function () { steps.dfn.onSubInput(list, this, rows, narrow); }); list.append($("<li></li>").append(next)); } }, build: function (stepDiv) { // Guard: only build once — refresh() calls build() on every // unrelated change, so skip if the list is already present. if (stepDiv.find("ol.wiktvi-dfn-list").length) return null; var list = $("<ol class='wiktvi-dfn-list'></ol>"); list.append(steps.dfn.buildSenseBlock(stepDiv)); stepDiv.append(list); return null; }, /** Reads all sense blocks from the DOM and returns an array of sense objects. */ getSenses: function (stepDiv) { var senses = []; stepDiv.find("li.wiktvi-dfn-sense").each(function () { var block = $(this); var tpl = block.find("select.wiktvi-dfn-tpl-select").val() || ""; var tplTitle = $.trim(block.find("input.wiktvi-dfn-tpl-title").val()); var mane = $.trim(block.find("textarea.wiktvi-dfn-mane").val()); var etiket = (function () { var vals = []; block.find(".wiktvi-dfn-etiket-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; }()); function readList(cls) { var vals = []; block.find("." + cls + "-list textarea").each(function () { var v = $.trim($(this).val()); if (v) vals.push(v); }); return vals; } senses.push({ tpl: tpl, tplTitle: tplTitle, mane: mane, etiket: etiket, nimune: readList("wiktvi-dfn-nimune"), herwiha: readList("wiktvi-dfn-herwiha"), hevmane: readList("wiktvi-dfn-hevmane"), dijmane: readList("wiktvi-dfn-dijmane"), koordine: readList("wiktvi-dfn-koordine"), jornav: readList("wiktvi-dfn-jornav"), jernav: readList("wiktvi-dfn-jernav") }); }); return senses; }, getOutput: function (values, callback) { var stepDiv = $("#wiktvi-start-dfn"); var senses = steps.dfn.getSenses(stepDiv); var lang = values.lang; // A sense counts as "filled" if it has either a mane or a chosen template + title. var hasMane = senses.some(function (s) { return s.mane !== "" || (s.tpl && s.tplTitle); }); // True only when at least one sense has a regular mane (needs linkify). var hasRegularMane = senses.some(function (s) { return !s.tpl && s.mane !== ""; }); var text = $.map(senses, function (sense) { // — Template sense (e.g. {{Guharto|ku|somepage}}) — if (sense.tpl) { if (!sense.tplTitle) return undefined; return "# {{" + sense.tpl + "|" + lang + "|" + escapeTemplateParam(sense.tplTitle) + "}}"; } // — Normal mane sense — var dfn = sense.mane; if (!dfn) return undefined; // Capitalize and punctuate. if (dfn[0] !== dfn[0].toUpperCase()) dfn = capitalize(dfn); if (!dfn.match(/[.…?!)\]]$/)) dfn += "."; // {{e|lang|label1|label2}} var labelTpl = ""; if (sense.etiket && sense.etiket.length) { var labelParts = sense.etiket.map(function (part) { return escapeTemplateParam($.trim(part)); }).filter(function (part) { return part !== ""; }); if (labelParts.length) { labelTpl = " {{e|" + lang + "|" + labelParts.join("|") + "}} "; } } var out = "#" + (labelTpl ? labelTpl : " ") + dfn; // Nimûne lines. out += formatNimune(sense.nimune, lang); // Per-sense word lists as #: template lines. function wordLine(tpl, words) { if (!words.length) return ""; return "\n#: {{" + tpl + "|" + lang + "|" + words.map(escapeTemplateParam).join("|") + "}}"; } out += wordLine("herwiha-rêz", sense.herwiha); out += wordLine("hevmane", sense.hevmane); out += wordLine("dijmane", sense.dijmane); out += wordLine("termên koordîne", sense.koordine); out += wordLine("jornav", sense.jornav); out += wordLine("jêrnav", sense.jernav); return out; }).join("\n") + "\n\n"; if (!hasMane) { // No definitions entered — emit {{mane?}} with bênimûne. text = "# {{mane?|" + lang + "}}\n#* {{bênimûne|" + lang + "}}\n\n"; callback(text); return; } if (!hasRegularMane) { // All filled senses are template senses — no linkify needed. callback(text); return; } var didTryToLoad = function () { $.wiktviLinkify(text, callback); }; mw.loader.using("ext.gadget.linkify", didTryToLoad, didTryToLoad); } }, je: makeWordListStep("je", "jê", "Kelîmeyên jê çêbûyî binivîse", "Jê", "g"), tekildar: makeWordListStep("tekildar", "têkildar", "Kelîmeyên têkildarî vê kelîmeyê binivîse", "Têkildar", "g"), binereherwiha: makeWordListStep("binereherwiha", "binêre herwiha", "Kelîmeyên din ên eleqedar binivîse", "Binêre herwiha", "g"), etym: { id: "etym", name: "etîmolojî", visible: function (values) { return false; }, output: function (values) { if (values.lang === "ku") { return "==== Etîmolojî ====\n{{ji?|ku}}"; } return ""; } }, trans: { id: "trans", name: "werger", visible: function (values) { if (!(values.lang === "ku" && values.pos)) return false; // Hide Werger when at least one sense uses a template instead of a mane. var hasTemplateSense = false; $("#wiktvi-start-dfn li.wiktvi-dfn-sense").each(function () { if ($(this).find("select.wiktvi-dfn-tpl-select").val()) { hasTemplateSense = true; return false; // break } }); return !hasTemplateSense; }, disabledKeys: { "navz": true, "ku": true }, /** * Builds one translation row: a language dropdown + a growing list * of word inputs. When the dropdown gets a value the next empty row * is appended automatically. */ buildRow: function (stepDiv) { var row = $("<li class='wiktvi-trans-row'></li>"); // Language selector — chosen is applied after insertion into DOM. var langSel = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); langSel.attr("data-placeholder", "Zimanekî hilbijêre"); populateMenus(langSel, steps.trans.keys || [], steps.trans.disabledKeys); // When a language is chosen, ensure a next empty row exists. langSel.on("change", function () { steps.trans.onLangChange(stepDiv, row); }); // Word list for this language. var wordList = $("<ul class='wiktvi-trans-words'></ul>"); var firstWord = steps.trans.makeWordInput(); wordList.append($("<li></li>").append(firstWord)); if (isMobile) { row.append(wrapNativeSelect(langSel)).append(wordList); } else { row.append(langSel).append(wordList); } return row; }, makeWordInput: function () { var input = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .attr("placeholder", "Tercime…"); input.on("input", function () { var list = $(this).closest("ul.wiktvi-trans-words"); var item = $(this).parent(); var val = $.trim($(this).val()); if (val && item.is(list.children("li:last-child"))) { var next = steps.trans.makeWordInput(); list.append($("<li></li>").append(next)); } }); return input; }, onLangChange: function (stepDiv, row) { var list = stepDiv.find("ul.wiktvi-trans-list"); var isLast = row.is(list.children("li.wiktvi-trans-row:last-child")); if (isLast) { var newRow = steps.trans.buildRow(stepDiv); list.append(newRow); // Init chosen after the new row is in the DOM (desktop only). if (!isMobile) newRow.find("select").chosen(chosenOptions); } // Keep disabled keys in sync across all lang selectors. steps.trans.syncDisabledKeys(stepDiv); }, /** Disables already-selected languages in all other dropdowns. */ syncDisabledKeys: function (stepDiv) { var taken = $.extend({}, steps.trans.disabledKeys); stepDiv.find("li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row select.wiktvi-start-step-keyfield," + "li.wiktvi-trans-row .chosen-single").end() .find("li.wiktvi-trans-row select").each(function () { var v = $(this).val(); if (v) taken[v] = true; }); stepDiv.find("li.wiktvi-trans-row select").each(function () { var self = $(this); var own = self.val(); self.find("option").each(function () { var code = $(this).val(); if (!code) return; $(this).prop("disabled", taken[code] && code !== own); }); self.trigger("chosen:updated"); }); }, build: function (stepDiv) { if (stepDiv.find("ul.wiktvi-trans-list").length) return null; var list = $("<ul class='wiktvi-trans-list'></ul>"); list.append(steps.trans.buildRow(stepDiv)); stepDiv.append(list); // Init chosen after the select is in the DOM (desktop only). if (!isMobile) list.find("select").chosen(chosenOptions); return null; }, /** Reads all translation rows from the DOM. */ getTranslations: function (stepDiv) { var result = []; stepDiv.find("li.wiktvi-trans-row").each(function () { var lang = $(this).find("select").val(); if (!lang) return; var words = []; $(this).find("ul.wiktvi-trans-words textarea").each(function () { var v = $.trim($(this).val()); if (v) words.push(v); }); if (words.length) result.push([lang, words]); }); return result; }, output: function (values) { if (values.lang !== "ku") return ""; var stepDiv = $("#wiktvi-start-trans"); var rows = steps.trans.getTranslations(stepDiv); var outputString = "\n\n==== Werger ====\n{{werger-ser}}"; if (rows.length) { // Sort by Kurdish sort key. rows.sort(function (a, b) { var aLang = langsByCode[a[0]] || []; var bLang = langsByCode[b[0]] || []; return (aLang[2] || "").localeCompare(bLang[2] || "", "ku"); }); outputString += "\n" + $.map(rows, function (row) { var lang = row[0]; var words = row[1].map(escapeTemplateParam); var wikiWords = words.map(function (w) { return "{{W|" + lang + "|" + w + "}}"; }).join(", "); return "* {{Z|" + lang + "}}: " + wikiWords; }).join("\n"); } outputString += "\n{{werger-bin}}\n\n"; return outputString; } }, }; steps.trans.keys = steps.lang.choices; var ordered_steps = [ steps.lang, steps.pron, steps.pos, steps.cinsiyet, steps.lektur, steps.tr, steps.dfn, steps.je, steps.tekildar, steps.binereherwiha, steps.etym, steps.trans]; // Step ids that belong to each section (not shared across sections). var PER_SECTION_STEP_IDS = [ "pos", "cinsiyet", "lektur", "tr", "dfn", "je", "tekildar", "binereherwiha", "etym", "trans" ]; // ── Multi-section state ────────────────────────────────────────────────── // Each entry is a plain snapshot: { pos, cinsiyet, lektur, tr, dfn (senses[]), // je, tekildar, binereherwiha, trans (rows[]) }. var sections = [{}]; // section 0 starts empty (DOM is the truth) var activeSection = 0; /** * Read dfn senses from DOM into a serialisable array. * Extends getSenses() with the template fields. */ function snapshotDfn() { return steps.dfn.getSenses($("#wiktvi-start-dfn")); } /** * Rebuild the dfn DOM from a previously snapshotted senses array. */ function restoreDfn(senses) { var stepDiv = $("#wiktvi-start-dfn"); // Tear down the existing list so build() recreates it cleanly. stepDiv.find("ol.wiktvi-dfn-list").remove(); steps.dfn.build(stepDiv); var list = stepDiv.find("ol.wiktvi-dfn-list"); $.each(senses, function (i, sense) { // Ensure enough blocks exist (build() seeds one). var blocks = list.find("li.wiktvi-dfn-sense"); var block = blocks.eq(i); if (!block.length) { var nb = steps.dfn.buildSenseBlock(stepDiv); list.append(nb); block = list.find("li.wiktvi-dfn-sense").last(); } // Template selector. block.find("select.wiktvi-dfn-tpl-select").val(sense.tpl || ""); if (sense.tpl) { block.find("textarea.wiktvi-dfn-mane").hide(); block.find("input.wiktvi-dfn-tpl-title").val(sense.tplTitle || "").show(); } else { block.find("textarea.wiktvi-dfn-mane").val(sense.mane || "").show(); block.find("input.wiktvi-dfn-tpl-title").hide().val(""); } // Restore a sub-list (etiket, nimune, herwiha …) from a values array. function restoreSubList(cls, values) { if (!values || !values.length) return; var groupDiv = block.find("." + cls + "-group"); // If the group hasn't been revealed yet, click its link. if (!groupDiv.length) { var needle = cls.replace("wiktvi-dfn-", "").toLowerCase(); block.find("a.wiktvi-dfn-lazy-toggle").filter(function () { return $(this).text().toLowerCase().indexOf(needle) !== -1; }).trigger("click"); groupDiv = block.find("." + cls + "-group"); } var subList = groupDiv.find("ol, ul").first(); // Fill existing items, append new ones as needed. $.each(values, function (j, val) { var items = subList.find("li"); if (j < items.length) { items.eq(j).find("textarea").val(val); } else { var ta = $("<textarea></textarea>") .attr("rows", 1) .attr("class", "wiktvi-dfn-subfield wiktvi-start-narrow") .val(val); ta.on("input", function () { steps.dfn.onSubInput(subList, this, 1, true); }); subList.append($("<li></li>").append(ta)); } }); } // Reveal and populate lazy groups that have data. var lazyMap = { "wiktvi-dfn-etiket": sense.etiket, "wiktvi-dfn-herwiha": sense.herwiha, "wiktvi-dfn-hevmane": sense.hevmane, "wiktvi-dfn-dijmane": sense.dijmane, "wiktvi-dfn-koordine": sense.koordine, "wiktvi-dfn-jornav": sense.jornav, "wiktvi-dfn-jernav": sense.jernav }; $.each(lazyMap, function (cls, vals) { if (vals && vals.length) restoreSubList(cls, vals); }); // Nimûne is always visible. restoreSubList("wiktvi-dfn-nimune", sense.nimune); }); } /** * Snapshot simple (non-dfn) per-section steps from current DOM into obj. */ function saveCurrentSection() { var snap = {}; $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { snap.dfn = snapshotDfn(); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktvi-start-" + id); if (id === "trans") { snap.trans = steps.trans.getTranslations(stepDiv); return; } // Generic: read all step fields. var fields = stepDiv.find(".wiktvi-start-step-field"); if (step.multiple) { snap[id] = fields.map(function () { return $(this).val(); }).get(); } else { snap[id] = fields.val(); } }); sections[activeSection] = snap; } /** * Restore a previously saved snapshot into the form DOM. */ function restoreSection(snap) { $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { restoreDfn(snap.dfn || []); return; } if (id === "trans") { // Rebuild trans rows. var transDiv = $("#wiktvi-start-trans"); transDiv.find("ul.wiktvi-trans-list").remove(); steps.trans.build(transDiv); var rows = snap.trans || []; $.each(rows, function (i, row) { var lang = row[0], words = row[1]; var list = transDiv.find("ul.wiktvi-trans-list"); var lastRow = list.find("li.wiktvi-trans-row").last(); lastRow.find("select").val(lang).trigger("change"); $.each(words, function (j, word) { var wordItems = lastRow.find("ul.wiktvi-trans-words li"); if (j < wordItems.length) { wordItems.eq(j).find("textarea").val(word); } }); }); return; } var step = steps[id]; if (!step) return; var stepDiv = $("#wiktvi-start-" + id); var fields = stepDiv.find(".wiktvi-start-step-field"); var val = snap[id]; if (val === undefined || val === null) return; if (step.multiple) { var arr = val; fields.each(function (i) { if (i < arr.length) $(this).val(arr[i]); }); } else { fields.val(val); } // Notify chosen widgets of the programmatic value change. if (!isMobile) fields.filter("select").trigger("chosen:updated"); }); } /** * Produce wikitext for the currently-visible form state. * This is identical to the old getWikitext but returns via callback. */ function getWikitextForCurrentSection(callback) { var values = getValues(); var entry = steps.pos.output(values); steps.dfn.getOutput(values, function (output) { entry += output; entry += steps.je.output(values); entry += steps.tekildar.output(values); entry += steps.binereherwiha.output(values); entry += steps.etym.output(values); entry += steps.trans.output(values); callback(entry, values); }); } /** * Collect wikitext from ALL sections by save→restore→generate cycling, * then restore the originally active section. */ function getWikitextAllSections(callback) { saveCurrentSection(); var results = new Array(sections.length); var sharedValues = getValues(); // lang/pron are shared function processSection(i) { if (i >= sections.length) { // All done — restore original active section. restoreSection(sections[activeSection]); refresh(); callback(results, sharedValues); return; } restoreSection(sections[i]); refresh(); getWikitextForCurrentSection(function (sectionText) { results[i] = sectionText; processSection(i + 1); }); } processSection(0); } /** * The original getWikitext — now assembles all sections plus lang header. */ function getWikitext(callback) { getWikitextAllSections(function (sectionTexts, sharedValues) { var entry = steps.lang.output(sharedValues); entry += steps.pron.output(sharedValues); entry += sectionTexts.join("\n"); // Edit summary uses section 0's values. var dfnSenses = steps.dfn.getSenses($("#wiktvi-start-dfn")); var dfnSummary = dfnSenses.map(function (s) { return s.mane; }).filter(Boolean).join("; "); var summary = "([[Mediawiki:Gadget-start.js|WF:Nû]]) +" + sharedValues.lang + ":" + sections[0].pos + ":" + dfnSummary; document.getElementById("wpSummary").value = summary; callback(entry); }); } var continueBtn; function getValuesForStep(stepId) { var fields = $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field"); var step = steps[stepId]; if (step.keys) { var values = {}; fields.each(function (i, field) { var key = $(field).prevAll(".wiktvi-start-step-keyfield").val(); if (key) values[key] = $(field).val(); }); return values; } else if (step.multiple) { return fields.map(function (i) { return $(this).val(); }).get(); } return fields.val(); } function getValues() { var values = {}; $.each(steps, function (stepId) { values[stepId] = getValuesForStep(stepId); }); return values; } function populateMenus(inputs, choices, disabledValues) { if (!disabledValues) disabledValues = {}; var vals = inputs.map(function (i, input) { return $(input).val(); }); inputs.empty(); inputs.append($("<option></option>")); $.each(choices, function (j, choice) { // Append the language code in parentheses so that typing a code // (e.g. "ku") in the search box still finds the language name. var displayText = capitalize(choice[1]); if (choice[2] !== undefined) { // This is a language choice [code, name, sortKey] — show code. displayText = capitalize(choice[1]) + " (" + choice[0] + ")"; } var option = $(mw.html.element("option", { value: choice[0] }, displayText)); if (disabledValues[choice[0]]) option.prop("disabled", true); inputs.append(option); }); inputs.val(function (i) { return vals[i]; }); } /** * Returns a bitmap containing the keys that should be disabled for a key * menu in the given step because they are disabled or already taken by * another key menu. */ function getDisabledKeys(step) { var occupiedKeys = {}; $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").each(function (i, select) { occupiedKeys[$(this).val()] = true; }); if (step.disabledKeys) $.extend(occupiedKeys, step.disabledKeys); return occupiedKeys; } function buildKeyInput(step) { if (!step.keys) return undefined; var input = $(mw.html.element("select", { "class": "wiktvi-start-step-keyfield wiktvi-start-narrow" })); input.attr("data-placeholder", "Hilbijêre " + step.keyName); if (isMobile) { populateMenus(input, step.keys, getDisabledKeys(step)); // On mobile return the wrapper; the select is inside it. // Change events still fire on the inner select. return wrapNativeSelect(input); } input.on("chosen:showing_dropdown", function (evt, context) { $(this).data("wiktvi-defaultValue", $(this).val()); }); input.change(function (evt, context) { var inputs = $("#wiktvi-start-" + step.id + " .wiktvi-start-step-keyfield").not(this); var oldValue = $(this).data("wiktvi-defaultValue"); var newValue = context.selected; inputs.find("option[value='" + oldValue + "']").prop('disabled', false); inputs.find("option[value='" + newValue + "']").prop('disabled', true); inputs.trigger("chosen:updated"); }); populateMenus(input, step.keys, getDisabledKeys(step)); return input; } /** * If the current text field has text and there are no more text fields after * the current text field in the list, add another text field to the list. */ function refreshForTextField(currentInput, step) { currentInput = $(currentInput); var value = currentInput.val(); var item = currentInput.parent(); if (value && !item.next("li").length) { var nextInput = $("<textarea></textarea>") .attr("class", currentInput.attr("class")) .attr("rows", currentInput.attr("rows") || 1); nextInput.on("input", function (evt) { refreshForTextField(evt.target, step); }); var nextKeyInput = buildKeyInput(step); var nextItem = $("<li></li>").append(nextKeyInput).append(nextInput); item.parent().append(nextItem); if (nextKeyInput) nextKeyInput.chosen(chosenOptions); } var canContinue = !continueBtn.prop("disabled"); if ((value && !canContinue) || (!value && canContinue)) { refresh(step); } } function prepareInput(input, step) { if (!input) return; if (step.required) input.prop('required', true); input.change(step, refresh); } /** * Shows and hides all the steps based on whether their prerequisites are met, * and updates placeholders where applicable. */ function refresh(evt) { var values = getValues(); var changedStep = evt && evt.data; var didFocus = false; var canContinue = true; // Re-filter template options in every sense block whenever lang changes. $("#wiktvi-start-dfn .wiktvi-dfn-tpl-select").each(function () { var fn = $(this).data("updateOptions"); if (typeof fn === "function") fn(); }); $.each(steps, function (stepId, step) { if (typeof(step.visible) === "function" && !step.visible(values)) { $("#wiktvi-start-" + stepId).slideUp(); // $("#wiktvi-start-" + stepId + " .wiktvi-start-step-field").val(""); } else { var stepDiv = $("#wiktvi-start-" + stepId); if (changedStep !== step && typeof(step.build) === "function") { prepareInput(step.build(stepDiv, values), step); } var input = stepDiv.find(".wiktvi-start-step-field"); if (typeof(step.example) === "function") { input.attr("placeholder", step.example(values) || ""); } var didSlideDown; if (!didFocus && stepDiv.css("display") === "none" && step.required) { didSlideDown = function (evt) { input.focus(); }; didFocus = true; } stepDiv.slideDown(didSlideDown); } if (step.required && (values[stepId] === "" || (step.multiple && values[stepId].join("") === ""))) { canContinue = false; } }); continueBtn.button(canContinue ? "enable" : "disable"); } function destroy() { $("#wiktvi-start-form, .noafterwizard").slideUp(function () { $(this).remove(); }); $(".noarticletext .nowizard, #editform").slideDown(); $("#ca-edit").removeClass("selected"); $("#ca-wiktvi-nowizard").addClass("selected"); } function build() { $(".nowizard, .nowizard .noafterwizard").hide(); var callToAction = $("#wiktvi-calltoaction"); var origCallToActionText = callToAction.text(); $(mw.util.addPortletLink("p-views", "#", "Edîtora çavkaniyê veke", "ca-wiktvi-nowizard", "Vê rûpelê bi edîtora çavkaniyê çêke", undefined, "#ca-watch")).click(function (evt) { evt.preventDefault(); callToAction.text(origCallToActionText); destroy(); }); callToAction.text(origCallToActionText + " Forma li jêr ji bo çêkirina madeyeke nû bi kar bîne."); var startForm = $("<form id='wiktvi-start-form'></form>"); var spinner; // Tab bar for switching between POS sections. var sectionTabsDiv = $("<div id='wiktvi-section-tabs'></div>"); startForm.submit(function (evt) { evt.preventDefault(); continueBtn.button("disable"); spinner.show(); getWikitext(function (wikitext) { $("#wpTextbox1").val(wikitext); $("html, body").animate({scrollTop: 0}); callToAction.text("Hindik ma!"); $("#wiktvi-preview-container").remove(); destroy(); }); }); $.each(ordered_steps, function (i, step) { var stepDiv = $(mw.html.element("div", { "class": "wiktvi-start-step", id: "wiktvi-start-" + step.id })); var name = capitalize(step.name); stepDiv.append($(mw.html.element("h3", { "class": "wiktvi-start-step-name" }, new mw.html.Raw(mw.html.element("label", { "for": "wiktvi-start-" + step.id + "-field" }, name))))); if (step.question_fmt) { var question = step.question_fmt.replace(/\{\{PAGENAME\}\}/g, pageName); stepDiv.append($(mw.html.element("label", { "class": "wiktvi-start-step-question", "for": "wiktvi-start-" + step.id + "-field" }, question))); if (step.question_br) stepDiv.append($("<br>")); } var input; // Menu if (step.choices) { input = $(mw.html.element("select", { "class": "wiktvi-start-step-field", id: "wiktvi-start-" + step.id + "-field" })); input.attr("data-placeholder", capitalize(step.name) + " hilbijêre "); populateMenus(input, step.choices); if (step.multiple) input.attr("multiple", true); if (isMobile) { stepDiv.append(wrapNativeSelect(input)); } else { stepDiv.append(input); } } // Custom else if (typeof(step.build) === "function") { input = step.build(stepDiv); } // Text field(s) else { input = $("<textarea></textarea>") .attr("class", "wiktvi-start-step-field") .attr("id", "wiktvi-start-" + step.id + "-field") .attr("rows", step.rows || 1); if (step.narrow) input.addClass("wiktvi-start-narrow"); if (step.multiple) { input.on("input", function (evt) { refreshForTextField(evt.target, step); }); var keyInput = buildKeyInput(step); var list = $(step.ordered ? "<ol></ol>" : "<ul></ul>") .append($("<li></li>").append(keyInput).append(input)); stepDiv.append(list); } else stepDiv.append(input); } prepareInput(input, step); stepDiv.hide(); // Insert tab bar just before the first per-section step. if (step.id === "pos") startForm.append(sectionTabsDiv); startForm.append(stepDiv); }); // ── Section tab helpers ────────────────────────────────────────────── /** Re-render the tab bar to reflect current sections[] and activeSection. */ function renderSectionTabs() { sectionTabsDiv.empty(); $.each(sections, function (i) { var label = steps.pos ? (sections[i].pos || ("Beş " + (i + 1))) : ("Beş " + (i + 1)); // Use the stored pos value for the label if available. var posVal = sections[i].pos || ""; var tabLabel = posVal ? capitalize(posVal) : ("Beş " + (i + 1)); var tab = $("<span></span>") .addClass("wiktvi-section-tab") .text(tabLabel) .toggleClass("wiktvi-tab-active", i === activeSection); (function (idx) { tab.on("click", function () { if (idx === activeSection) return; saveCurrentSection(); // Update label of tab we're leaving with its pos. var leavingPos = sections[activeSection].pos || ""; activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); }); }(i)); sectionTabsDiv.append(tab); }); } /** Switch to section idx, saving current first. */ function switchToSection(idx) { if (idx === activeSection) return; saveCurrentSection(); activeSection = idx; restoreSection(sections[activeSection]); refresh(); renderSectionTabs(); } renderSectionTabs(); // Update the active tab's label whenever pos changes. startForm.on("change", "#wiktvi-start-pos-field", function () { renderSectionTabs(); }); var footer = $("<div id='wiktvi-start-footer'></div>"); spinner = $(mw.html.element("img", { id: "wiktvi-start-spinner", src: "//upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif", alt: "Tê barkirin…", title: "Tê barkirin…" })); footer.append(spinner.hide()); continueBtn = $(mw.html.element("button", { id: "wiktvi-unhide-editform", type: "submit" }, "Bişîne")); footer.append(continueBtn); // ── Add-section button ─────────────────────────────────────────────── var addSectionBtn = $(mw.html.element("button", { id: "wiktvi-add-section", type: "button" }, "+ Beş zêde bike")); addSectionBtn.css("margin-left", "6px"); addSectionBtn.on("click", function () { saveCurrentSection(); sections.push({}); // new empty section activeSection = sections.length - 1; // Clear all per-section fields so the new section starts blank. $.each(PER_SECTION_STEP_IDS, function (_, id) { if (id === "dfn") { var stepDiv = $("#wiktvi-start-dfn"); stepDiv.find("ol.wiktvi-dfn-list").remove(); steps.dfn.build(stepDiv); return; } if (id === "trans") { var transDiv = $("#wiktvi-start-trans"); transDiv.find("ul.wiktvi-trans-list").remove(); return; } var stepDiv = $("#wiktvi-start-" + id); stepDiv.find(".wiktvi-start-step-field").val(""); if (!isMobile) stepDiv.find("select.wiktvi-start-step-field").trigger("chosen:updated"); }); renderSectionTabs(); refresh(); // Scroll to the tab bar so the user sees the new section. $("html, body").animate({ scrollTop: sectionTabsDiv.offset().top - 20 }, 300); }); footer.append(addSectionBtn); // ── Preview checkboxes ─────────────────────────────────────────────── // Wikitext preview (raw text panel) var previewCheck = $("<input type='checkbox' id='wiktvi-preview-toggle'>"); var previewLabel = $("<label for='wiktvi-preview-toggle'></label>") .text(" Pêşdîtina wîkîtekstê"); var previewPanel = $("<pre id='wiktvi-preview-panel'></pre>").hide(); // Live rendered preview (parsed HTML panel, same logic as AjaxEdit) var livePreviewCheck = $("<input type='checkbox' id='wiktvi-live-preview-toggle'>"); var livePreviewLabel = $("<label for='wiktvi-live-preview-toggle'></label>") .text(" Pêşdîtina zindî"); var livePreviewPanel = $("<div id='wiktvi-live-preview-panel'></div>").css({ "margin-top": "1em", "padding": "0.8em", "background": "#f8f9fa", "border": "1px solid #a2a9b1", "word-break": "break-word", "min-height": "2em" }).hide(); // Container that holds both panels and switches between stacked / side-by-side. var previewContainer = $("<div id='wiktvi-preview-container'></div>").css({ "display": "flex", "flex-wrap": "wrap", "gap": "1em", "margin-top": "0.5em" }); previewContainer.append(previewPanel).append(livePreviewPanel); var previewTimer = null; var livePreviewIntervalId = -1; /** Rebuilds wikitext preview if its checkbox is checked. */ function schedulePreview() { if (!previewCheck.prop("checked")) return; clearTimeout(previewTimer); // Debounce: wait 400 ms after the last keystroke before rebuilding. previewTimer = setTimeout(function () { getWikitext(function (wikitext) { previewPanel.text(wikitext).show(); updatePanelLayout(); }); }, 400); } /** Fetches parsed HTML and populates the live preview panel. */ function loadLivePreview() { getWikitext(function (wikitext) { new mw.Api().parse(wikitext, { title: mw.config.get("wgPageName") }).done(function (html) { livePreviewPanel.html(html).show(); updatePanelLayout(); }); }); } /** Adjusts panel widths depending on which previews are visible. */ function updatePanelLayout() { var wikitextVisible = previewCheck.prop("checked"); var liveVisible = livePreviewCheck.prop("checked"); if (wikitextVisible && liveVisible) { // Side by side — each panel takes roughly half the available width. previewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); livePreviewPanel.css({ "flex": "1 1 45%", "min-width": "280px" }); } else { // Full width for whichever is visible. previewPanel.css({ "flex": "1 1 100%", "min-width": "" }); livePreviewPanel.css({ "flex": "1 1 100%", "min-width": "" }); } } previewCheck.on("change", function () { if ($(this).prop("checked")) { schedulePreview(); } else { clearTimeout(previewTimer); previewPanel.hide(); updatePanelLayout(); } }); livePreviewCheck.on("change", function () { if ($(this).prop("checked")) { livePreviewPanel.show(); loadLivePreview(); livePreviewIntervalId = setInterval(loadLivePreview, 500); } else { clearInterval(livePreviewIntervalId); livePreviewIntervalId = -1; livePreviewPanel.hide().empty(); updatePanelLayout(); } }); // Listen on all input/change events on the form and update both previews. startForm.on("input change", function () { schedulePreview(); }); footer.append($("<span style='margin-left:1em'></span>") .append(previewCheck).append(previewLabel)); footer.append($("<span style='margin-left:1em'></span>") .append(livePreviewCheck).append(livePreviewLabel)); startForm.append(footer); $("#editform").hide().before(startForm); // Insert preview container (holds both panels) after the form. startForm.after(previewContainer); if (!isMobile) startForm.find("select").chosen(chosenOptions); continueBtn.button(); refresh(); // Zimanan ji MediaWiki:Gadget-translation_editor.js/ziman.json bar bike. // Kodên ku bi "-pro" diqedin û navên ku "zimanê destan" tê de heye // tên derxistin. Zimanên xardkirî li serî dimînin, yên din // bi alfabeyê li dû wan tên. var pinnedCodes = ["ku", "zza", "ckb", "sdh", "de", "ar", "fa", "fr", "fi", "en", "sv", "tr"]; var pinnedChoices = steps.lang.choices.slice(); // copy of the initial 9 new mw.Api().get({ action: "query", prop: "revisions", titles: "MediaWiki:Gadget-translation_editor.js/ziman.json", rvprop: "content", rvslots: "main", formatversion: 2 }).then(function (data) { var page = data.query.pages[0]; var content = page && page.revisions && page.revisions[0].slots.main.content; var zimanData; try { zimanData = JSON.parse(content); } catch (e) { zimanData = {}; } var extraChoices = []; $.each(zimanData, function (code, name) { // Filter: skip proto-language codes and legendary/reconstructed langs. if (/-pro$/i.test(code)) return; if (/ziman[eê]\s+destan/i.test(name)) return; // Skip codes already in the pinned list (they are handled above). if (pinnedCodes.indexOf(code) !== -1) return; // sortKey: bare name without leading "zimanê " for sorting. var sortKey = name.replace(/^ziman[eê]\s+/i, ""); var choice = [code, name, sortKey]; extraChoices.push(choice); langsByCode[code] = choice; }); // Populate langsByCode for pinned choices too. $.each(pinnedChoices, function (i, choice) { // Ensure pinned choices have a sortKey (index 2). if (choice.length < 3) choice[2] = choice[1]; langsByCode[choice[0]] = choice; }); // Sort the extra choices alphabetically by sort key. extraChoices.sort(function (a, b) { return a[2].localeCompare(b[2], userLang); }); // Final list: pinned first, then the rest. var allChoices = pinnedChoices.concat(extraChoices); steps.lang.choices = allChoices; steps.trans.keys = allChoices; var langMenu = $("#wiktvi-start-lang-field"); populateMenus(langMenu, steps.lang.choices); langMenu.trigger("chosen:updated"); var transMenus = $("#wiktvi-start-trans .wiktvi-start-step-keyfield"); populateMenus(transMenus, steps.trans.keys, getDisabledKeys(steps.trans)); transMenus.trigger("chosen:updated"); }); } mw.loader.using(["jquery.chosen", "jquery.ui", "mediawiki.api"], build); }); //</nowiki> 5ruccnws9r5kr3fa2sx86y1j72bzx3b Bikarhêner:Wikihez/skrîpt/js/TranslationAdder-Data.js 2 1325562 6241568 6101182 2026-07-10T18:40:11Z Wikihez 7344 6241568 javascript text/javascript // {{documentation}} [[en:MediaWiki:Gadget-TranslationAdder-Data.js]] // <nowiki> // implicit dependencies : ext.gadget.LanguageUtils /* jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true */ /* global $, ScriptUtils, mw */ window.LangMetadata = function() { //Singleton if (arguments.callee.instance) return arguments.callee.instance; else arguments.callee.instance = this; // {{{ Metadata dictionaries // FIXME: Is it possible to query this information directly from [[Module:languages]]? var metadata = { aa: { haswikt: 1, sc: ["Latn", "Ethi"] }, ab: { haswikt: 1, sc: ["Cyrl", "Latn", "Geor"] }, aer: { sc: "Latn" }, af: { g: ["y", "p"], haswikt: 1 }, ak: { haswikt: 1 }, akk: { g: ["n", "m", "n-p", "m-p"], sc: "Xsux" }, als: { haswikt: 1 }, am: { g: ["n", "m", "n-p", "m-p"], haswikt: 1, sc: "Ethi" }, an: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, ang: { alt: 1, g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1 }, ar: { g: ["n", "m", "n-p", "m-p", "p"], alt: 1, haswikt: 1, sc: "Arab" }, arc: { g: ["n", "m", "n-p", "m-p"], sc: ["Hebr", "Syrc"] }, are: {}, arz: { alt: 1, g: ["n", "m", "n-p", "m-p"], sc: "Arab" }, as: { haswikt: 1, sc: "Beng" }, ast: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, av: { haswikt: 1 }, ay: { haswikt: 1 }, az: { g: ["y", "p"], haswikt: 1, sc: ["Latn", "Cyrl", "Arab"] }, ba: { g: ["y", "p"], sc: "Cyrl" }, bar: {}, "bat-smg": { g: ["n", "m", "n-p", "m-p"] }, bbl: { sc: "Geor" }, be: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1, sc: "Cyrl" }, "be-x-old": { sc: "Cyrl" }, bg: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1, sc: "Cyrl" }, bh: { haswikt: 1, sc: "Deva" }, bhb: { sc: "Deva" }, bi: { haswikt: 1 }, blt: { sc: "Tavt" }, bm: { haswikt: 1, sc: ["Latn", "Nkoo", "Arab"] }, bn: { haswikt: 1, sc: "Beng" }, bo: { haswikt: 1, sc: "Tibt" }, br: { g: ["n", "m"], haswikt: 1 }, ca: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, cdo: { sc: "Hani" }, ce: { sc: "Cyrl" }, ch: { haswikt: 1 }, chr: { haswikt: 1, sc: "Cher" }, cjy: { sc: "Hani" }, ckb: { haswikt: 1, sc: "Arab", wsc: "ku-Arab" }, cmn: { sc: "Hani", wiktprefix: "zh" }, co: { haswikt: 1 }, cpx: { sc: "Hani" }, cr: { haswikt: 1, sc: "Cans" }, crh: {}, cs: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1 }, csb: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1 }, cu: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], sc: ["Cyrs", "Glag"] }, cv: { sc: "Cyrl" }, cy: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, czh: { sc: "Hani" }, czo: { sc: "Hani" }, da: { g: ["g", "nt", "g-p", "nt-p", "p"], haswikt: 1 }, dax: {}, de: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], haswikt: 1, allowCaps: 1 }, dhg: {}, djb: {}, dji: {}, djr: {}, dng: { sc: "Cyrl" }, dsb: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"] }, dsx: {}, duj: {}, dv: { g: ["y", "p"], haswikt: 1, sc: "Thaa" }, dz: { haswikt: 1, sc: "Tibt" }, el: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1 }, en: { g: ["y", "p"], haswikt: 1 }, eo: { g: ["y", "p"], haswikt: 1 }, es: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1 }, et: { g: ["y", "p"], haswikt: 1 }, ett: { g: ["y", "p"], sc: "Ital" }, eu: { g: ["y", "p"], haswikt: 1 }, fa: { haswikt: 1, g: ["y", "p"], sc: "Arab", wsc: "fa-Arab" }, // modelling on cmn, nb, prs "fa-cls": { wiktprefix: "fa", sc: "Arab", wsc: "fa-Arab" }, // modelling on cmn, nb, prs "fa-ira": { wiktprefix: "fa", sc: "Arab", wsc: "fa-Arab" }, fi: { g: ["y", "p"], haswikt: 1 }, fil: {}, fj: { haswikt: 1 }, fo: { g: ["n", "m", "nt"], haswikt: 1 }, fr: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1 }, frm: { g: ["n", "m", "n-p", "m-p"] }, fro: { g: ["n", "m", "n-p", "m-p"] }, fur: { g: ["n", "m", "n-p", "m-p"], }, fy: { g: ["g", "nt", "p"], haswikt: 1 }, ga: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1 }, gan: { sc: "Hani" }, gd: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, gez: { sc: "Ethi" }, gl: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, "gmw-ecg": { g: ["n", "m", "nt", "p"], allowCaps: 1 }, gmy: { sc: "Linb" }, gn: { haswikt: 1 }, gnn: { sc: "Latn" }, got: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], sc: "Goth" }, grc: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"] }, gsw: { g: ["n", "m", "nt", "p"], allowCaps: 1 }, gu: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1, sc: "Gujr" }, guf: { sc: "Latn" }, gv: { haswikt: 1 }, ha: { haswikt: 1 }, hak: { sc: "Hani" }, har: { sc: "Ethi" }, he: { alt: 1, g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1, sc: "Hebr" }, hi: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1, sc: "Deva" }, hif: { sc: ["Latn", "Deva"] }, hit: { sc: "Xsux" }, hrx: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1 }, hsb: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1 }, hsn: { sc: "Hani" }, hu: { g: ["y", "p"], haswikt: 1 }, hy: { g: ["y", "p"], haswikt: 1, sc: "Armn" }, ia: { haswikt: 1 }, id: { haswikt: 1 }, ie: { haswikt: 1 }, ik: { haswikt: 1 }, ike: { sc: "Cans" }, ikt: { sc: "Cans" }, io: { haswikt: 1 }, is: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1 }, it: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1 }, iu: { haswikt: 1, sc: "Cans" }, ja: { haswikt: 1, sc: "Jpan" }, jay: { sc: "Latn" }, jbo: { haswikt: 1 }, jv: { haswikt: 1 }, ka: { g: ["y", "p"], haswikt: 1 }, // script should include "Geok" for Asomtavruli & Nuskhuri but prevents automatic transliteration? khb: { sc: ["Talu", "Lana", "Thai"] }, kjh: { sc: "Cyrl" }, kk: { haswikt: 1, g: ["y", "p"], sc: "Cyrl" }, kkh: { sc: ["Lana", "Thai"] }, kl: { haswikt: 1 }, km: { haswikt: 1, sc: "Khmr" }, kn: { haswikt: 1, sc: "Knda" }, ku: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], wiktprefix: "ku" }, ko: { haswikt: 1, sc: "Kore" }, krc: { g: ["y", "p"], sc: "Cyrl" }, ks: { haswikt: 1, sc: ["Arab", "Deva"], wsc: "ks-Arab" }, kw: { haswikt: 1 }, ky: { haswikt: 1, g: ["y", "p"], sc: "Cyrl" }, la: { alt: 1, g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1 }, lb: { g: ["n", "m", "nt", "p"], haswikt: 1, allowCaps: 1 }, lez: { sc: "Cyrl" }, li: { haswikt: 1 }, lki: { wiktprefix: "ku" }, lld: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, lmo: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, ln: { haswikt: 1 }, lo: { haswikt: 1, sc: "Laoo" }, lt: { alt: 1, g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, lv: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, lzz: { sc: "Geor" }, mg: { haswikt: 1 }, mh: { haswikt: 1 }, mi: { g: 0, haswikt: 1 }, mk: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1, sc: "Cyrl" }, ml: { haswikt: 1, sc: "Mlym" }, mn: { g: ["y", "p"], haswikt: 1, sc: ["Cyrl", "Mong"] }, mnp: { sc: "Hani" }, mo: { haswikt: 1, sc: "Cyrl" }, mol: { sc: "Cyrl" }, mr: { g: ["n", "m", "nt"], haswikt: 1, sc: "Deva" }, ms: { haswikt: 1, sc: ["Latn", "Arab"] }, mt: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1 }, mwp: { sc: "Latn" }, my: { haswikt: 1, sc: "Mymr" }, na: { haswikt: 1 }, nah: { haswikt: 1 }, nan: { wiktprefix: "zh-min-nan", sc: "Hani" }, nb: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], wiktprefix: "no" }, "nds-de": { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], wiktprefix: "nds" }, "nds-nl": { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], wiktprefix: "nds" }, ne: { haswikt: 1, sc: "Deva" }, nl: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], haswikt: 1 }, nn: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], haswikt: 1 }, no: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], haswikt: 1 }, nod: { sc: "Lana" }, non: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"] }, oc: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, om: { haswikt: 1 }, or: { haswikt: 1, sc: "Orya" }, orv: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], sc: "Cyrs" }, osc: { sc: "Ital" }, ota: { g: ["y", "p"], sc: "Arab", wsc: "ota-Arab" }, pa: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1, sc: ["Guru", "Arab"] }, pdt: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], wiktprefix: "nds" }, peo: { sc: "Xpeo" }, phn: { sc: "Phnx" }, pi: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1 }, pjt: { sc: "Latn" }, pl: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1 }, pms: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, pox: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "împf", "pf"] }, prs: { wiktprefix: "fa", sc: "Arab", wsc: "fa-Arab" }, ps: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1, sc: "Arab", wsc: "ps-Arab" }, pt: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1 }, qu: { haswikt: 1 }, rgn: { g: ["n", "m", "n-p", "m-p"], }, rit: { sc: "Latn" }, rm: { g: ["n", "m"], haswikt: 1 }, rn: { haswikt: 1 }, ro: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], haswikt: 1, sc: ["Latn", "Cyrl"] }, "roa-rup": { haswikt: 1 }, ru: { alt: 1, g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1, sc: "Cyrl" }, rue: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], sc: "Cyrl" }, ruo: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"] }, rup: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], wiktprefix: "roa-rup" }, ruq: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"] }, rw: { haswikt: 1 }, sa: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"], haswikt: 1, sc: "Deva" }, sah: { sc: "Cyrl" }, sc: { haswikt: 1 }, scn: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, sco: { sc: "Latn" }, sd: { haswikt: 1, sc: "Arab", wsc: "sd-Arab" }, sdh: { wiktprefix: "ku" }, sg: { haswikt: 1 }, sh: { alt: 1, g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1, sc: ["Latn", "Cyrl"] }, si: { haswikt: 1, sc: "Sinh" }, simple: { haswikt: 1 }, sk: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1 }, sl: { alt: 1, g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1 }, sm: { haswikt: 1 }, sn: { haswikt: 1 }, so: { haswikt: 1 }, spx: { sc: "Ital" }, sq: { g: ["n", "m"], haswikt: 1 }, ss: { haswikt: 1 }, st: { haswikt: 1 }, su: { haswikt: 1 }, sux: { sc: "Xsux" }, sv: { g: ["g", "nt", "g-p", "nt-p"], haswikt: 1 }, sva: { sc: "Geor" }, sw: { nclass: 1, haswikt: 1 }, syc: { sc: "Syrc" }, syr: { sc: "Syrc" }, szl: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"] }, ta: { haswikt: 1, sc: "Taml" }, tdd: { sc: "Tale" }, te: { haswikt: 1, sc: "Telu" }, tg: { g: ["y", "p"], haswikt: 1, sc: "Cyrl" }, th: { haswikt: 1, sc: "Thai" }, ti: { haswikt: 1, sc: "Ethi" }, tig: { sc: "Ethi" }, tiw: { sc: "Latn" }, tk: { g: ["y", "p"], haswikt: 1 }, tl: { haswikt: 1, sc: ["Latn", "Tglg"] }, tmr: { sc: "Hebr" }, tn: { haswikt: 1 }, to: { haswikt: 1 }, tpi: { haswikt: 1 }, tr: { g: ["y", "p"], alt: 1, haswikt: 1 }, ts: { haswikt: 1 }, tt: { g: ["y", "p"], haswikt: 1 }, tts: { sc: "Thai" }, tw: { haswikt: 1 }, udi: { sc: ["Cyrl", "Latn", "Armn", "Geor"] }, ug: { g: ["y", "p"], haswikt: 1, sc: "Arab", wsc: "ug-Arab" }, uga: { sc: "Ugar" }, uk: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p", "împf", "pf"], haswikt: 1, sc: "Cyrl" }, ulk: { sc: "Latn" }, ur: { g: ["n", "m", "n-p", "m-p", "p"], haswikt: 1, sc: "Arab", wsc: "ur-Arab" }, uz: { g: ["y", "p"], haswikt: 1 }, vec: { g: ["n", "m", "n-p", "m-p"], haswikt: 1 }, vi: { haswikt: 1 }, vls: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p"] }, vo: { haswikt: 1 }, wa: { haswikt: 1 }, wbp: { sc: "Latn" }, wo: { haswikt: 1 }, wuu: { sc: "Hani" }, xae: { sc: "Ital" }, xcr: { sc: "Cari" }, xfa: { sc: "Ital" }, xh: { alt: 1, nclass: 1, haswikt: 1 }, xlc: { sc: "Lyci" }, xld: { sc: "Lydi" }, xlu: { sc: "Xsux" }, xmf: { sc: "Geor" }, xno: { g: ["n", "m", "n-p", "m-p"] }, xrr: { sc: "Ital" }, xst: { sc: "Ethi" }, xum: { sc: "Ital" }, xve: { sc: "Ital" }, xvo: { sc: "Ital" }, yi: { g: ["n", "m", "nt", "n-p", "m-p", "nt-p", "p"], haswikt: 1, sc: "Hebr" }, yo: { haswikt: 1 }, yua: { g: ["y", "p"], alt: 1 }, yue: { sc: "Hani" }, za: { haswikt: 1, sc: "Latn" }, "zh-classical": { sc: "Hani" }, "zh-min-nan": { haswikt: 1 }, "zh-yue": { sc: "Hani" }, zu: { alt: 1, nclass: 1, haswikt: 1 } }; var clean = { aar: "aa", afar: "aa", abk: "ab", abkhazian: "ab", afr: "af", afrikaans: "af", aka: "ak", akan: "ak", amh: "am", amharic: "am", ara: "ar", arabic: "ar", arg: "an", aragonese: "an", asm: "as", assamese: "as", ava: "av", avaric: "av", ave: "ae", avestan: "ae", aym: "ay", aymara: "ay", aze: "az", azerbaijani: "az", bak: "ba", bashkir: "ba", bam: "bm", bambara: "bm", bel: "be", belarusian: "be", ben: "bn", bengali: "bn", bis: "bi", bislama: "bi", bod: "bo", tibetan: "bo", bs: "sh", bos: "sh", bosnian: "sh", bre: "br", breton: "br", bul: "bg", bulgarian: "bg", cat: "ca", catalan: "ca", ces: "cs", czech: "cs", cha: "ch", chamorro: "ch", che: "ce", chechen: "ce", chu: "cu", churchslavic: "cu", chv: "cv", chuvash: "cv", cor: "kw", cornish: "kw", cos: "co", corsican: "co", cre: "cr", cree: "cr", cym: "cy", welsh: "cy", dan: "da", danish: "da", deu: "de", german: "de", div: "dv", dhivehi: "dv", dzo: "dz", dzongkha: "dz", ekk: "et", ell: "el", greek: "el", eng: "en", english: "en", epo: "eo", esperanto: "eo", est: "et", estonian: "et", eus: "eu", basque: "eu", ewe: "ee", fao: "fo", faroese: "fo", fas: "fa", //"fa-ira": "fa", //"fa-cls": "fa", //prs: "fa", persian: "fa", fij: "fj", fijian: "fj", fil: "tl", fin: "fi", finnish: "fi", fra: "fr", french: "fr", fry: "fy", westernfrisian: "fy", ful: "ff", fulah: "ff", gla: "gd", scottishgaelic: "gd", gle: "ga", irish: "ga", glg: "gl", galician: "gl", glv: "gv", manx: "gv", grn: "gn", guarani: "gn", guj: "gu", gujarati: "gu", hat: "ht", haitian: "ht", hau: "ha", hausa: "ha", heb: "he", hebrew: "he", her: "hz", herero: "hz", hin: "hi", hindi: "hi", hmo: "ho", hirimotu: "ho", hr: "sh", hrv: "sh", croatian: "sh", hun: "hu", hungarian: "hu", hye: "hy", armenian: "hy", ibo: "ig", igbo: "ig", ido: "io", iii: "ii", sichuanyi: "ii", iku: "iu", inuktitut: "iu", ile: "ie", interlingue: "ie", ina: "ia", interlingua: "ia", ind: "id", indonesian: "id", ipk: "ik", inupiaq: "ik", isl: "is", icelandic: "is", ita: "it", italian: "it", jav: "jv", javanese: "jv", jpn: "ja", japanese: "ja", kal: "kl", kalaallisut: "kl", kan: "kn", kannada: "kn", kas: "ks", kashmiri: "ks", kat: "ka", georgian: "ka", kau: "kr", kanuri: "kr", kaz: "kk", kazakh: "kk", khm: "km", centralkhmer: "km", kik: "ki", kikuyu: "ki", kin: "rw", kinyarwanda: "rw", kir: "ky", kirghiz: "ky", kom: "kv", komi: "kv", kon: "kg", kongo: "kg", kor: "ko", korean: "ko", ksh: "gmw-cfr", kua: "kj", kuanyama: "kj", kv: "kpv", lao: "lo", lat: "la", latin: "la", lav: "lv", latvian: "lv", lim: "li", limburgan: "li", lin: "ln", lingala: "ln", lit: "lt", lithuanian: "lt", ltz: "lb", luxembourgish: "lb", lub: "lu", lubakatanga: "lu", lug: "lg", ganda: "lg", mah: "mh", marshallese: "mh", mal: "ml", malayalam: "ml", mar: "mr", marathi: "mr", chm: "mhr", mari: "mhr", mkd: "mk", macedonian: "mk", mlg: "mg", malagasy: "mg", mlt: "mt", maltese: "mt", mon: "mn", mongolian: "mn", mri: "mi", maori: "mi", msa: "ms", malay: "ms", mya: "my", burmese: "my", nau: "na", nauru: "na", hokkien: "nan-hbl", hokkienese: "nan-hbl", fujian: "nan-hbl", fujianese: "nan-hbl", hainam: "hnm", hainan: "hnm", hainanese: "hnm", leizhou: "luh", "zhx-lui": "luh", teochew: "nan-tws", teochewese: "nan-tws", "zhx-teo": "nan-tws", wep: "nds-de", westphalian: "nds-de", germanlowgerman: "nds-de", dutchlowsaxon: "nds-nl", act: "nds-nl", achterhoeks: "nds-nl", drt: "nds-nl", drents: "nds-nl", gos: "nds-nl", gronings: "nds-nl", sdz: "nds-nl", sallands: "nds-nl", stl: "nds-nl", stellingwerfs: "nds-nl", twd: "nds-nl", twents: "nds-nl", vel: "nds-nl", veluws: "nds-nl", nav: "nv", navajo: "nv", nbl: "nr", southndebele: "nr", nde: "nd", northndebele: "nd", ndo: "ng", ndonga: "ng", nep: "ne", nepali: "ne", nld: "nl", dutch: "nl", flemish: "nl", nno: "nn", norwegiannynorsk: "nn", nob: "nb", norwegianbokmal: "nb", nor: "no", norwegian: "no", nya: "ny", nyanja: "ny", oci: "oc", occitan: "oc", oji: "oj", ojibwa: "oj", ori: "or", oriya: "or", orm: "om", oromo: "om", oss: "os", ossetian: "os", pan: "pa", panjabi: "pa", pfl: "gmw-rfr", pli: "pi", pali: "pi", pol: "pl", polish: "pl", por: "pt", portuguese: "pt", pus: "ps", pushto: "ps", que: "qu", quechua: "qu", roh: "rm", romansh: "rm", ron: "ro", romanian: "ro", rn: "rw", run: "rw", rundi: "rw", rus: "ru", russian: "ru", sag: "sg", sango: "sg", san: "sa", sanskrit: "sa", sin: "si", sinhala: "si", slk: "sk", slovak: "sk", slv: "sl", slovenian: "sl", sme: "se", northernsami: "se", smo: "sm", samoan: "sm", sna: "sn", shona: "sn", snd: "sd", sindhi: "sd", som: "so", somali: "so", sot: "st", southernsotho: "st", spa: "es", spanish: "es", sqi: "sq", albanian: "sq", srd: "sc", sardinian: "sc", sr: "sh", srp: "sh", serbian: "sh", ssw: "ss", swati: "ss", sun: "su", sundanese: "su", swa: "sw", swahili: "sw", swe: "sv", swedish: "sv", tah: "ty", tahitian: "ty", tam: "ta", tamil: "ta", tat: "tt", tatar: "tt", tel: "te", telugu: "te", tgk: "tg", taishanese: "zhx-tai", tajik: "tg", tgl: "tl", tagalog: "tl", tha: "th", thai: "th", tir: "ti", tigrinya: "ti", ton: "to", tonga: "to", tsn: "tn", tswana: "tn", tso: "ts", tsonga: "ts", tuk: "tk", turkmen: "tk", tur: "tr", turkish: "tr", twi: "tw", uig: "ug", uighur: "ug", ukr: "uk", ukrainian: "uk", urd: "ur", urdu: "ur", uzb: "uz", uzbek: "uz", ven: "ve", venda: "ve", vie: "vi", vietnamese: "vi", westflemish: "vls", vol: "vo", volapuk: "vo", wln: "wa", walloon: "wa", wol: "wo", wolof: "wo", xho: "xh", xhosa: "xh", yid: "yi", yiddish: "yi", yor: "yo", yoruba: "yo", zbc: "lod", zbe: "lod", zbw: "lod", zha: "za", zhuang: "za", zh: "cmn", zho: "cmn", chinese: "cmn", zul: "zu", zulu: "zu", }; // }}} // FIXME: merge into above var c = 'Çînî'; var a = 'Erebî'; var nesting = { aae: 'Albanî/Arbëreş', aat: 'Albanî/Arvanitika', als: 'Albanî/Tosk', aln: 'Albanî/Gheg', apj: 'Apaçî', apm: 'Apaçî', apw: 'Apaçî', //Bai bca: 'Bayî/Bayiya navendî', bfc: 'Bayî/Bayiya bakurî', bfs: 'Bayî/Bayiya başûrî', lay: 'Bayî/Lama baiyî', //Eastern Cham (cjm) and Western Cham (cja) to be nested under Cham (atitarev) cjm: 'Çamî/Çamiya rojhilatî', cja: 'Çamî/Çamiya rojavayî', syr: 'Aramî', syc: 'Aramî', xcl: 'Ermenî', axm: 'Ermenî', // ang:'English',enm:'English', don't nest English (Encyclopetey) //Persian nesting prs: 'Farisî/Darî', "fa-cls": 'Farisî/Farisiya klasîk', "fa-ira": 'Farisî/Farisiya îranî', fro: 'Fransî', frm: 'Fransî', oge: 'Gurcî', gsw: 'Almanî', ksh: 'Almanî', pfl: 'Almanî', //gmh:'German',goh:'German', don't nest OHG/MHG (-sche) grc: 'Yûnanî/Yûnaniya kevn', gmy: 'Yûnanî/Yûnaniya mîkenî', //el:'Greek/Modern', don't nest Modern Greek (Atelaes) sga: 'Îrlendî', mga: 'Îrlendî', ckb: 'Kurdî/Soranî', sdh: 'Kurdî/Kurdiya Başûrî', lki: 'Kurdî/Kurdiya lekî', //Lawa lwl: 'Lawayî/Lawayiya rojhilatî', lcp: 'Lawayî/Lawayiya rojavayî', "nds-de": 'Low German', "nds-nl": 'Low German', nb: 'Norwêcî/Bokmål', nn: 'Norwêcî/Nynorsk', mhr: 'Marî/Mariya rojhilatî', mrj: 'Marî/Mariya rojavayî', cmg: 'Mongolî', cst: 'Ohlonî/Ohloniya bakur', css: 'Ohlonî/Ohloniya başûr', //Roglai rog: 'Roglayî/roglayiya bakurî', rgs: 'Roglayî/roglayiya başûrî', roc: 'Roglayî/Cacgia roglaî', rmn: 'Romanî', rml: 'Romanî', rmc: 'Romanî', rmf: 'Romanî', rmo: 'Romanî', rmy: 'Romanî', rmw: 'Romanî', dsb: 'Sorbî', hsb: 'Sorbî', osp: 'Spanî', //Sama ssb: 'Samayî/Samayiya başûrî', sml: 'Samayî/Samayiya navendî', sse: 'Samayî/Samayiya balangingî', slm: 'Samayî/Pangutaran samayî', //Sami sma: 'Samî/samiya başûr', sju: 'Samî/Ume samî', sje: 'Samî/Pite samî', smj: 'Samî/Samiya lule', sme: 'Samî/Samiya bakurî', sjk: 'Samî/Kemi samî', smn: 'Samî/Samiya înarî', sms: 'Samî/Samiya skoltî', sia: 'Samî/Samiya akkalayî', sjd: 'Samî/Samiya kildînî', sjt: 'Samî/Ter samî', tji: 'Tujiayî/Tujiayiya bakurî', tjs: 'Tujiayî/Tujyayiya başûrî', owl: 'Weylsî', wlm: 'Weylsî', "yok-bvy": 'Yokutsî', "yok-dly": 'Yokutsî', "yok-gsy": 'Yokutsî', "yok-kry": 'Yokutsî', "yok-nvy": 'Yokutsî', "yok-ply": 'Yokutsî', "yok-svy": 'Yokutsî', "yok-tky": 'Yokutsî', zh: c, yue: c, dng: c, gan: c, hak: c, czh: c, cjy: c, cmn: c, mnp: c, cdo: c, nan: c, czo: c, cpx: c, wuu: c, hsn: c, lzh: c, cnp: c, csp: c, ltc: c, och: c, wxa: c, "nan-hbl": c, hnm: c, luh: c, "nan-tws": c, "zhx-sht": c, "zhx-sic": c, "zhx-tai": c, arq: a, aao: a, bbz: a, abv: a, shu: a, acy: a, adf: a, avl: a, arz: a, afb: a, ayh: a, acw: a, ayl: a, acm: a, ary: a, ars: a, apc: a, ayp: a, acx: a, aec: a, ayn: a, ssh: a, ajp: a, arb: a, apd: a, pga: a, acq: a, abh: a, aeb: a, auz: a }; var stripArabicDiacritics = { strip: "\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652" }; var stripGraveAndAcute = { strip: "\u0300\u0301" }; var fullToHalfWidthNumbers = { from: "0123456789", to: "0123456789" }; // These should reflect the replacements made in [[Module:languages]], but should not necessarily be equal. var diacriticStrippers = { ang: { from: "ĀāǢǣĊċĒēĠġĪīŌōŪūȲȳ", to: "AaÆæCcEeGgIiOoUuYy", strip: "\u0304\u0307", }, //macron and above dot ar: stripArabicDiacritics, aao: stripArabicDiacritics, acm: stripArabicDiacritics, acx: stripArabicDiacritics, adf: stripArabicDiacritics, aeb: stripArabicDiacritics, afb: stripArabicDiacritics, ajp: stripArabicDiacritics, apc: stripArabicDiacritics, apd: stripArabicDiacritics, arq: stripArabicDiacritics, ary: stripArabicDiacritics, arz: stripArabicDiacritics, fa: stripArabicDiacritics, ps: stripArabicDiacritics, sd: stripArabicDiacritics, ur: stripArabicDiacritics, chl: { from: "ÁáÉéÍíÓóÚú", to: "AaEeIiOoUu", strip: "\u0304", }, //acute accent he: { strip: "\u05B0\u05B1\u05B2\u05B3\u05B4\u05B5\u05B6\u05B7\u05B8\u05B9\u05BA\u05BB\u05BC\u05BD\u05BF\u05C1\u05C2", from: "-'\"", to: "־׳״", }, la: { from: "ĀāĒēĪīŌōŪūȲȳ", to: "AaEeIiOoUuYy", strip: "\u0304", }, //macron lt: { from: "áãàéẽèìýỹñóõòúù", to: "aaaeeeiyynooouu", strip: "\u0340\u0301\u0303", }, nci: { from: "ĀāĒēĪīŌōŪūȲȳ", to: "AaEeIiOoUu", strip: "\u0304", }, //macron //strip ́ and ̀ on Cyrillic Slavic languages, Serbo-Croatian has a longer list ru: stripGraveAndAcute, uk: stripGraveAndAcute, be: stripGraveAndAcute, bg: stripGraveAndAcute, orv: stripGraveAndAcute, cu: stripGraveAndAcute, rue: stripGraveAndAcute, mk: stripGraveAndAcute, sh: { from: "ȀȁÀàȂȃÁáĀāȄȅÈèȆȇÉéĒēȈȉÌìȊȋÍíĪīȌȍÒòȎȏÓóŌōȐȑȒȓŔŕȔȕÙùȖȗÚúŪūѝӣ", to: "AaAaAaAaAaEeEeEeEeEeIiIiIiIiIiOoOoOoOoOoRrRrRrUuUuUuUuUuии", strip: "\u030F\u0300\u0311\u0301\u0304", }, sl: { from: "áÁàÀâÂȃȂȁȀéÉèÈêÊȇȆȅȄíÍìÌîÎȋȊȉȈóÓòÒôÔȏȎȍȌŕŔȓȒȑȐúÚùÙûÛȗȖȕȔệỆộỘẹẸọỌəł", to: "aAaAaAaAaAeEeEeEeEeEiIiIiIiIiIoOoOoOoOoOrRrRrRuUuUuUuUuUeEoOeEoOel", strip: "\u0301\u0300\u0302\u0311\u030f\u0323", }, kk: stripGraveAndAcute, ky: stripGraveAndAcute, tg: stripGraveAndAcute, sa: { strip: "ः", }, /** visarga **/ bo: { strip: "།", }, /** shad **/ tr: { from: "ÂâÛû", to: "AaUu", strip: "\u0302", }, ja: fullToHalfWidthNumbers, cmn: fullToHalfWidthNumbers, yue: fullToHalfWidthNumbers, nan: fullToHalfWidthNumbers, ko: fullToHalfWidthNumbers, zu: { strip_init_hyphen: true, } }; function stringOrNull(val) { return typeof val == "string" ? val : null; } function makeMap(obj) { var from = stringOrNull(obj.from); var to = stringOrNull(obj.to); var strip = stringOrNull(obj.strip); var map = {}; if (from && to) { for (var i = 0; i < from.length; i++) { map[from.charAt(i)] = to.charAt(i); } } if (strip) { for (var ii = 0; ii < strip.length; ii++) { map[strip.charAt(ii)] = ""; } } return map; } /** letters and number 1 are used instead of palochka **/ var palochkaCorrections = { from: "Il1", to: "ӏӏӏ" }; // var arabicYa = "ي"; // Arabic letter yāʾ (U+064A ARABIC LETTER YEH) var arabicKaf = "ك"; // Arabic letter kāf (U+0643 ARABIC LETTER KAF) var farsiYe = "ی"; // Persian letter ye (U+06CC ARABIC LETTER FARSI YEH) var farsiKaf = "ک"; // Persian letter kâf (U+06A9 ARABIC LETTER KEHEH) var alifMaqsura = "ى"; // Arabic letter ʾalif maqṣūra (U+0649 ARABIC LETTER ALEF MAKSURA) /** commonly misspelled Persian letters (Arabic instead of Persian) (to be expanded) **/ var persianCorrections = { from: arabicKaf + arabicYa + alifMaqsura, to: farsiKaf + farsiYe + farsiYe, }; // These replacements will be applied when a word is submitted. var orthographicalCorrections = { // Replace grave accents with acute accents for translations // into Bulgarian per Wiktionary policy bg: { map: { "\u0300": "\u0301", "Ѐ": "Е́", "Ѝ": "И́", "ѐ": "е́", "ѝ": "и́" }, }, abq: palochkaCorrections, ady: palochkaCorrections, av: palochkaCorrections, ce: palochkaCorrections, dar: palochkaCorrections, inh: palochkaCorrections, kbd: palochkaCorrections, lbe: palochkaCorrections, lez: palochkaCorrections, tab: palochkaCorrections, /** Roman to Cyrillic**/ cv: { from: "ĂăĔĕÇçŸÿ", to: "ӐӑӖӗҪҫӲӳ", }, kv: { from: "ÖöIi", to: "ӦӧІі", }, koi: { from: "ÖöIi", to: "ӦӧІі", }, kpv: { from: "ÖöIi", to: "ӦӧІі", }, os: { from: "Ææ", to: "Ӕӕ", }, /* Obsolete or incorrectly used letters */ mn: { from: "ЄєѲѳЇїVv", to: "ӨөӨөҮүҮү", strip: "\u0300\u0301", }, /* cedilla to comma below */ ro: { from: "ŞŢşţ", to: "ȘȚșț", }, /** ʻ is a standard symbol in Uzbek but is often replaced with ' or ` **/ uz: { from: "'`", to: "ʻʻ", }, fa: persianCorrections, "fa-ira": persianCorrections, "fa-cls": persianCorrections, prs: persianCorrections, ur: persianCorrections, /** commonly misspelled Arabic letters (Persian instead of Arabic) (to be expanded) **/ ar: { from: farsiKaf + farsiYe, to: arabicKaf + arabicYa, }, ota: { from: farsiKaf + arabicYa + alifMaqsura, to: arabicKaf + farsiYe + farsiYe, }, ps: { from: arabicKaf, to: farsiKaf, }, /** some letters are considered more standard (to be expanded) **/ cu: { from: "ыѹ", to: "ꙑу", }, /** some letters are considered more standard (to be expanded) **/ orv: { from: "ыѹ", to: "ꙑу", }, /** obsolete letters **/ ab: { from: "ҔҕҦҧ", to: "ӶӷԤԥ", }, }; //Returns true if a Wiktionary exists for the specified language this.hasWiktionary = function(lang) { if (metadata[lang] && (metadata[lang].haswikt || metadata[lang].wiktprefix)) return true; }; //Returns the domain-name prefix of the Wiktionary for the specified language this.getWiktionaryPrefix = function(lang) { if (metadata[lang]) return metadata[lang].wiktprefix || (metadata[lang].haswikt && lang); }; // Keep this in sync with ignore_caps in [[Module:translations]]. this.ignoreCaps = { "ko": true }; // Calls the callback with a boolean indicating whether the specified language // has a Wiktionary with the specified entry. The callback might be called // synchronously, or it might be called asynchronously. this.hasWiktionaryWithEntry = function(lang, title, callback) { if (this.hasWiktionary(lang)) { if (this.ignoreCaps[lang]) title = title.replace(/^\^/, ""); // Use this when we want to give up support for Internet Explorer 11. // URL constructor and URLSearchParams are not supported in IE11. // var url = new URL("https://" + this.getWiktionaryPrefix(lang) + ".wiktionary.org/w/api.php"); // url.search = new URLSearchParams({ // "format": "json", // "formatversion": "2", // "action": "query", // "titles": title, // "converttitles": 1, // "origin": "*", // }); var url = new mw.Uri("https://" + this.getWiktionaryPrefix(lang) + ".wiktionary.org/w/api.php"); url.extend({ "format": "json", "formatversion": "2", "action": "query", "titles": title, "converttitles": 1, "origin": "*", }); $.ajax({ type: 'GET', url: url.toString(), dataType: 'json', headers: { 'Api-User-Agent': 'EnWiktTranslationAdderGadget/0.0 (https://en.wiktionary.org/wiki/MediaWiki:Gadget-TranslationAdder.js)' }, }).done(function(data) { var page = data && data.query && data.query.pages && data.query.pages[0]; callback(page instanceof Object ? !page.missing : false); }); } else callback(false); }; //Given a language code return a default script code. this.guessScript = function(lang) { var scripts = (new ScriptUtils()).GetScriptsByLangCode(lang); if (scripts && scripts.length > 0) return scripts[0]; else return false; if (metadata[lang]) { // enwikt language template? (ur-Arab, polytonic) if (metadata[lang].wsc) { return metadata[lang].wsc; } // ISO script code? (Arab, Grek) if (metadata[lang].sc) { if (typeof metadata[lang].sc == 'object') return metadata[lang].sc[0]; else return metadata[lang].sc; } } return false; }; // In a given language, would we expect a translation of the title to have the capitalisation // of word? this.expectedCase = function(lang, title, word) { if (metadata[lang] && metadata[lang].allowCaps) return true; if (title.substr(0, 1).toLowerCase() != title.substr(0, 1)) return true; return word.substr(0, 1).toLowerCase() == word.substr(0, 1); }; //Returns a string of standard gender letters (mfnc) or an empty string this.getGenders = function(lang) { if (metadata[lang]) return metadata[lang].g; }; //Returns a string of standard noun class numbers or an empty string this.hasNounClasses = function(lang) { if (metadata[lang]) return metadata[lang].nclass; }; //Returns true if the specified lang uses optional vowels or diacritics this.needsRawPageName = function(lang) { if (metadata[lang]) return metadata[lang].alt && !diacriticStrippers[lang]; }; function applyMap(map, str) { var input = str.split(""); var output = ""; for (var i = 0; i < input.length; i++) { var char = input[i]; var repl = map[char]; output += repl ? repl : char; } return output; } this.applyOrthographicalCorrections = function(lang, word) { word = word.replace('\xAD', ''); // remove soft hyphens var corrections = orthographicalCorrections[lang]; if (corrections) { var map = corrections.map ? corrections.map : makeMap(corrections); return applyMap(map, word); } return word; }; // Computes the raw page name by removing diacritics (for Latin, etc.) this.computeRawPageName = function(lang, word) { var stripper = diacriticStrippers[lang]; if (stripper) { var map = makeMap(stripper); var output = applyMap(map, word); if (stripper.strip_init_hyphen && output.length > 0 && output.charAt(0) == '-') output = output.substr(1); return output; } }; // Calls [[Module:links]]'s 'remove_diacritics' method on word and rawPageName, // and invokes callback with two arguments: (1) the *real* raw page name // (superseding even rawPageName), and (2) whether this real raw page name // needs to be explicitly specified in the wikitext (i.e., whether the raw page // name computed from rawPageName is different from the one that would have been // computed from just word). this.retrieveRawPageName = function(lang, word, rawPageName, callback) { var ents = { '<': 'lt', '&': 'amp', '>': 'gt' }; var temps = { '|': '!', '=': '=', '{': '(', '}': ')' }; function encode(s) { s = s || ''; s = s.replace(/[|={}]/g, function(c) { return '{{' + temps[c] + '}}'; }); s = s.replace(/[<&>]/g, function(c) { return '&' + ents[c] + ';'; }); s = s.replace(/\t/g, ' '); //s = encodeURIComponent(s); return s; } function removeDiacritics(s) { return '{{#invoke:languages/templates|getByCodeAllowEtym|' + lang + '|makeEntryName|' + encode(s) + '}}'; } var text = removeDiacritics(word) + '\t' + removeDiacritics(rawPageName || word); $.ajax({ dataType: "json", url: '/w/api.php', data: { format: 'json', action: 'expandtemplates', prop: 'wikitext', text: text }, success: function(data) { data = data && data.expandtemplates && data.expandtemplates.wikitext; if (/<!--/.test(data)) { data = false; } if (data) { data = data && data.split('\t'); var wordMinus = data[0]; var rawPageNameMinus = data[1]; callback(rawPageNameMinus || wordMinus, rawPageNameMinus != wordMinus); } else { callback(rawPageName || word, rawPageName && rawPageName != word); } } }); }; //Given user input, return a language code. Normalises ISO 639-1 codes and names to 639-3. this.cleanLangCode = function(lang) { var key = lang.toLowerCase().replace(' ', ''); if (clean[key]) return clean[key]; else return lang; }; // Get the nesting for a given sub-language this.getNested = function(lang) { if (nesting[lang]) return nesting[lang]; else return ""; }; function temporalSortKey(langname) { return langname.replace(/^(Ancient|Classical|Old|Middle|Early Modern|Modern) (.*)/, function(m, modifier, name) { return ({ Ancient: 0, Old: 1, Middle: 2, "Early Modern": 3, Modern: 4 })[modifier] + name; }); } // For enforcing an ordering on nested languages. this.nestsBefore = function(a, b) { return temporalSortKey(a) < temporalSortKey(b); }; this.getScripts = function(lang) { var scripts = (new window.ScriptUtils()).GetScriptsByLangCode(lang) || []; return scripts; }; }; //</nowiki> b2aoogw4rjs4qmfx46azszyrm1au2ph Şablon:ng 10 1326049 6241604 6106275 2026-07-11T05:08:52Z EmausBot 6143 Beralîkirina ducarî li ser [[Şablon:îzaha ne eleqedarî maneyê]] hat sererastkirin 6241604 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:îzaha ne eleqedarî maneyê]] l6abjyf7a8an8yvqgligls706k849f9 Şablon:n-g 10 1326219 6241603 6113113 2026-07-11T05:08:42Z EmausBot 6143 Beralîkirina ducarî li ser [[Şablon:îzaha ne eleqedarî maneyê]] hat sererastkirin 6241603 wikitext text/x-wiki #BERALÎKIRIN [[Şablon:îzaha ne eleqedarî maneyê]] l6abjyf7a8an8yvqgligls706k849f9 Bikarhêner:Wikihez/skrîpt/json/loader-settings.json 2 1357332 6241605 6238811 2026-07-11T08:39:04Z Wikihez 7344 Mîhengên Loaderê hatin nûkirin (bi rêza alfabetîk) 6241605 json application/json { "scripts": [ { "key": "etiketCeke", "label": "Etîket Çêke", "src": "Bikarhêner:Wikihez/skrîpt/loader/etîket-çêke.js", "info": "Ji bo şablona {{f}} etîketên nû li Modulê zêde dike.", "disabled": false }, { "key": "mass-delete-category", "label": "Jêbirina bi kom", "src": "Bikarhêner:Wikihez/skrîpt/js/delete.js", "info": "Rûpelên di kategoriyê de bi komî jê dibe (Taybet ji bo adminan)", "disabled": false }, { "key": "kopi-enwikt", "label": "Kopî enwikt", "src": "Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js", "info": "Rûpelan ji Wîkîferhenga îngilîzî kopî dike û girêdanên Wîkîdaneyê çêdike.", "disabled": false }, { "key": "test", "label": "test.js", "src": "Bikarhêner:Wikihez/test.js", "info": "Rûpel: Bikarhêner:Wikihez/test.js", "disabled": false } ] } lr2v2zlee3jkxejb3wiij2sjo61s2ge 6241606 6241605 2026-07-11T09:20:16Z Wikihez 7344 Restored revision 6238811 by [[Special:Contributions/Wikihez|Wikihez]] ([[User talk:Wikihez|talk]]) ([[:m:User:Xiplus/TwinkleGlobal|TwinkleGlobal]]) 6241606 json application/json { "scripts": [ { "key": "etiketCeke", "label": "Etîket Çêke", "src": "Bikarhêner:Wikihez/skrîpt/loader/etîket-çêke.js", "info": "Ji bo şablona {{f}} etîketên nû li Modulê zêde dike.", "disabled": false }, { "key": "mass-delete-category", "label": "Jêbirina bi kom", "src": "Bikarhêner:Wikihez/skrîpt/js/delete.js", "info": "Rûpelên di kategoriyê de bi komî jê dibe (Taybet ji bo adminan)", "disabled": false }, { "key": "kopi-enwikt", "label": "Kopî enwikt", "src": "Bikarhêner:Wikihez/skrîpt/js/kopi-enWikt.js", "info": "Rûpelan ji Wîkîferhenga îngilîzî kopî dike û girêdanên Wîkîdaneyê çêdike.", "disabled": false } ] } patlcxa5sx0f1rg8oicmxg7siy3qlfj پاشەڵ 0 1357373 6241602 6238619 2026-07-10T23:54:14Z Wikihez 7344 /* Navdêr */ 6241602 wikitext text/x-wiki == {{ziman|ckb}} == === Navdêr === {{navdêr|ckb}} # {{f|ckb|anatomî}} [[qorik]] {{îzah|hêla binî ya [[pişt|piştê]]}} 9fdg85r67kaadowykfz9gif4bpys323