Википедия lezwiki https://lez.wikipedia.org/wiki/%D0%9A%D1%8C%D0%B8%D0%BB%D0%B8%D0%BD_%D1%87%D1%87%D0%B8%D0%BD MediaWiki 1.48.0-wmf.1 first-letter Медиа Служебная Веревирд авун Уртах Уртахдин веревирд авун Википедия Википедия веревирд авун Файл Файл веревирд авун MediaWiki MediaWiki веревирд авун Шаблон Шаблон веревирд авун Справка Обсуждение справки Категория Категория веревирд авун TimedText TimedText talk Модуль Обсуждение модуля Event Event talk КцӀар 0 338 99904 99879 2026-11-02T13:09:53Z ~2026-58018-65 13315 /* */ 99904 wikitext text/x-wiki {{ЯШЧ2+ |тӀвар=КцӀар |статус= Шегьер |вичин чӀалал тӀвар = |ЯШЧдин статус = |уьлкве = Азербайжан |герб = Qusar.png |пайдах = |гербдин гьал = 100px |пайдахдин гьал = |гербдин гьяркьуьвал = |пайдахдин гьяркьуьвал = |lat_dir = |lat_deg=41 |lat_min=25 |lat_sec=19 |lon_dir = |lon_deg=48 |lon_min=25 |lon_sec=17 |CoordAddon = |CoordScale = |гьукуматдин картадин алцум =300 |региондин картадин алцум =300 |райондин картадин алцум =300 |региондин жуьре = |регион = Къуба-Хъачмаздин экономикадин регион |регион таблицада = |райондин жуьре = Муниципал район |район = КцӀар район‎ |жемятдин жуьре = |жемят = |жемят таблицада = |къенепатан паюнар = |кьилин жуьре = |кьил = |бине эцигай тарих = |виликан тӀварар = |статус йисалай = [[1938 йис]]уз шегьердин статус къачунва |кьакьанвилин жуьре = |ЯШЧдин кьакьанвал = |климат = |официал чӀал = |майдан = |агьалияр = {{гзаф хьун1}} 17 500 |сиягьдиз къачур йис = 2013 |къалинвал = |агломерация = |миллетар = [[лезгияр]], [[азербайжанaр]] |динар = [[сунияр|суни]] - [[мусурманар]] |чпи-чпиз гузвай тӀвар = |сятдин чӀул = +4, +5 |DST = |телефондин код = +994 23 |почтунин индекс = AZ 3800 |почтайрин индексар = |автомобилдин код = 38 |идентификатордин жуьре = |цифрадин идентификатор = |Commons-ра категория = Kusary |сайт = |сайтдин чӀал = |add1n = Хуьруьн шикилар |add1 = [http://www.azerbaijanphoto.com/cgi-bin/site/main2.cgi?choice=thelast;l=5;id=22608;s=5149 Azerbaijanphoto] |add2n = Космосдай акунар |add2 = [https://goo.gl/maps/2hJDL Google Map] }} '''КцӀар''' ({{lang-az|Qusar}}) — [[Азербайжан]] республикадин [[КцӀар район]]да авай [[ЦӀал|цIал]]. Райондин администрациядин юкь я. ==ТӀварцӀикай== КцӀар тӀварцӀин арадал атуникай чара-чара тарихдарри шумудни са баянар гузва. Виридалайни машгьур версиядив кьурвал, ''КцӀар'' гаф урус чӀалан ''Гусар'', яни кьушунрин жуьредикай сад тир «балкӀандал алай аскер» гафуникай арадал атана. Идан себеб, Урусатдин Империядин чӀавуз КцӀар [[ЦӀал|цIалина]] урусрин балкӀанрал алай аскеррин кьушунрин кӀеретӀар авай. Муькуь алимрин фикирдалди, ''КцӀар'' гаф ''«гъуц»'', ''«кьве сур»'' (кьисадив кьурвал, са мус ятӀа ина кьве лезгидин арада къал акъатнай, абуру сада сад яна кьинай, ахпа абур кьведни ина кучуднай), ''«ксар»'' (дегь алпандин тайифадин тӀвар) гафарикай арадал атанвайди мумкин я. ==Жугърафия== [[ЦӀал|ЦIал]] [[КцӀар район]]дин кьибле пата, [[Къуба район]]дихъ галаз часпара, [[КцӀар вацӀ]]ун кьерел, [[Баку]] шегьердилай 180 км яргъал ала. КцӀарин къвалав [[Фиалка]] тӀвар алай вир гала. ==Тарих== Кцlар [[ЦӀал|цIал]] Урус Чарвилин ч1авуз Къуба вилаятдин къене хьанвай чкарикай сад я. КцӀариз 1930-лагьа йисда Азербайжан Совет Сосиалист Республикадин гьукуматдин патала мухъ (район) ва [[ЦӀал|цIал]] статус ганвай. 1963-65 йисара КцIарин къене [[Хтар|Хт1ар]] [[ЦӀал|цIалини]] хьанад ахпа 1965-лагьа йисдиз ам легъвна Хачмаз мухъ (район) мад хъвуна. ==Агьалияр== Йисариз килигна шегьердин агьалийрин кьадар: {|class="wikitable" style="padding:0;background:#fafafa;border:1px solid #bbb;width:700px;height:70px;text-align:center;font-size:12px;cellspacing=0" |- |'''style="background: bgcolor="#CBD5C4" |'''Йис''' | '''[[1926 йис|1926]]''' | '''[[1939 йис|1939]]''' | '''[[1959 йис|1959]]''' | '''[[1970 йис|1970]]''' | '''[[1979 йис|1979]]''' | '''[[2009 йис|2009]]''' | '''[[2013 йис|2013]]''' |- |'''style="background: bgcolor="#CBD5C4" |'''Агьалияр''' | 2 996 | {{гзаф хьун1}} 4 329 | {{гзаф хьун1}} 7 366 | {{гзаф хьун1}} 11 144 | {{гзаф хьун1}} 12 017 | {{гзаф хьун1}} 16 466 | {{гзаф хьун1}} 17 500 |} <div class="center">'''Урусатдин, СССР-дин ва Азербайжандин агьалияр сиягьдиз къачунин малуматриз килигна КцӀар шегьердин миллетрин состав.'''</div> {| border="1" cellpadding="4" cellspacing="0" style="margin: 10px 0 10px 25px; width:900px; height:20px; background: #fafafa; border: 1px #AAA solid; border-collapse: collapse; font-size: 85%; float: center; text-align:center" |- style="background: #fafafa" |-bgcolor="#CBD5C4" | ''' Йис''' | '''1926 <ref>[http://www.ethno-kavkaz.narod.ru/kuba26.html Кубинский уезд (1926 г.)]</ref>''' | '''1939 <ref>[http://www.ethno-kavkaz.narod.ru/kusary39.html Кусарский район (1939 г.)]</ref>''' | '''1959 <ref>[http://www.ethno-kavkaz.narod.ru/kusary59.html Кусарский район (1959 г.)]</ref>''' | '''1970 <ref>[http://www.ethno-kavkaz.narod.ru/kusary70.html Кусарский район (1970 г.)]</ref>''' | '''1979 <ref>[http://www.ethno-kavkaz.narod.ru/kusary79.html Кусарский район (1979 г.)]</ref>''' |- |align="left"|'''[[лезгияр]]''' |430 (14,4 %) |{{гзаф хьун1}}2 104 (48,6 %) |{{гзаф хьун1}} 4 804 (65,2 %) |{{гзаф хьун1}}8 257 (74,1 %) |{{гзаф хьун1}}9 610 (80 %) |- |align="left"|'''[[азербайжанар]]''' |628 (21 %) |{{гзаф хьун1}}826 (19,1 %) |{{гзаф хьун1}}956 (13 %) |{{гзаф хьун1}}1 413 (12,7 %) |{{гзаф хьун1}}1 444 (12 %) |- |align="left"|'''[[урусар]]'''/ '''[[украинар]]''' |1 634 (54,6 %) |{{тӀимил хьун1}} 1 034 (23,9 %) |{{гзаф хьун1}} 1 050 (14,3 %) |{{тӀимил хьун1}}973 (8,7 %) |{{тӀимил хьун1}}585 (4,9 %) |- |align="left"|'''[[чувудар]]''' |120 (4 %) |{{гзаф хьун1}}241 (5,6 %) |{{тӀимил хьун1}}230 (3,1 %) |{{гзаф хьун1}}313 (2,8 %) |{{тӀимил хьун1}}173 (1,4 %) |- |align="left"|'''вири''' |{{гзаф хьун1}}'''2 996 (100 %)''' |{{гзаф хьун1}}'''4 329 (100 %)''' |{{гзаф хьун1}}'''7 366 (100 %)''' |{{гзаф хьун1}}'''11 144 (100 %)''' |{{гзаф хьун1}}'''12 017 (100 %)''' |} ==Икътисадийят== Шегьерда консерврин, некӀедин ва асфальт гьазурзавай заводар кардик ква. ==Меденийет ва чирвилер== [[1998 йис]]уз КцӀара Гьукуматдин лезги драм театр ахъайнай. [[2006 йис]]уз шегьерда 6 юкьван чирвилерин мектебар кӀвалахзавай, абурукай сад азербайжан вадни урус мектебар тир. Идалайни гъейри, шегьерда мектебдилай вилик гьазурвилер гудай чирвилерин идара, Азербайжандин Гьукуматдин Педагожи Колледж кардик ква. Колледжда азербайжан чӀалан, ингилис чӀалан ва адабийятдин муаллимар ва гьакӀни сифте кьилин мектебрин муаллимар гьазурзава. ==Улакь== ==Идман== ==Акунаравай - Машгьур инсанар== * [[Хъуьлуьхъ Гъази Мугьаммад]] - лезги имам * [[Аскеров Гьилал]] — лезги шаир ва журналист. * [[Ризванов Ризван Забитан хва]] — машгьур лезги шаир, тариххъан ва таржумахъан. * [[Эфендиев Ярмет Яверан хва]] — лезги шаир ва кхьираг. ==Килигуниз лайих тир чкаяр== Шагьдагъ, Лермонтован кlвал музей ==Эдебийят== * [http://ir.nmu.org.ua/bitstream/handle/123456789/112904/7473ef4328e7ca43214c1d233b92f000.pdf?sequence=1 М. М. Ихилов «Народы лезгинской группы»] {{Webarchive|url=https://web.archive.org/web/20150402140550/http://ir.nmu.org.ua/bitstream/handle/123456789/112904/7473ef4328e7ca43214c1d233b92f000.pdf?sequence=1 |date=2015-04-02 }} == Баянар == {{Баянар}} == ЭлячӀунар == * [http://www.kycap.com/city/history.html КцӀарин сайтунал шегьердин тарихдикай малуматар] {{КцӀар райондин яшамиш жезвай чкаяр}} [[Категория:КцӀар район]] [[Категория:Азербайжандин шегьерар]] [[Категория:Лезги шегьерар]] owj9n1fkgssw9gs4ttwrd6cm3z3j4w8 99911 99904 2026-11-03T04:25:58Z ~2026-58405-76 13318 /* Идман */ 99911 wikitext text/x-wiki {{ЯШЧ2+ |тӀвар=КцӀар |статус= Шегьер |вичин чӀалал тӀвар = |ЯШЧдин статус = |уьлкве = Азербайжан |герб = Qusar.png |пайдах = |гербдин гьал = 100px |пайдахдин гьал = |гербдин гьяркьуьвал = |пайдахдин гьяркьуьвал = |lat_dir = |lat_deg=41 |lat_min=25 |lat_sec=19 |lon_dir = |lon_deg=48 |lon_min=25 |lon_sec=17 |CoordAddon = |CoordScale = |гьукуматдин картадин алцум =300 |региондин картадин алцум =300 |райондин картадин алцум =300 |региондин жуьре = |регион = Къуба-Хъачмаздин экономикадин регион |регион таблицада = |райондин жуьре = Муниципал район |район = КцӀар район‎ |жемятдин жуьре = |жемят = |жемят таблицада = |къенепатан паюнар = |кьилин жуьре = |кьил = |бине эцигай тарих = |виликан тӀварар = |статус йисалай = [[1938 йис]]уз шегьердин статус къачунва |кьакьанвилин жуьре = |ЯШЧдин кьакьанвал = |климат = |официал чӀал = |майдан = |агьалияр = {{гзаф хьун1}} 17 500 |сиягьдиз къачур йис = 2013 |къалинвал = |агломерация = |миллетар = [[лезгияр]], [[азербайжанaр]] |динар = [[сунияр|суни]] - [[мусурманар]] |чпи-чпиз гузвай тӀвар = |сятдин чӀул = +4, +5 |DST = |телефондин код = +994 23 |почтунин индекс = AZ 3800 |почтайрин индексар = |автомобилдин код = 38 |идентификатордин жуьре = |цифрадин идентификатор = |Commons-ра категория = Kusary |сайт = |сайтдин чӀал = |add1n = Хуьруьн шикилар |add1 = [http://www.azerbaijanphoto.com/cgi-bin/site/main2.cgi?choice=thelast;l=5;id=22608;s=5149 Azerbaijanphoto] |add2n = Космосдай акунар |add2 = [https://goo.gl/maps/2hJDL Google Map] }} '''КцӀар''' ({{lang-az|Qusar}}) — [[Азербайжан]] республикадин [[КцӀар район]]да авай [[ЦӀал|цIал]]. Райондин администрациядин юкь я. ==ТӀварцӀикай== КцӀар тӀварцӀин арадал атуникай чара-чара тарихдарри шумудни са баянар гузва. Виридалайни машгьур версиядив кьурвал, ''КцӀар'' гаф урус чӀалан ''Гусар'', яни кьушунрин жуьредикай сад тир «балкӀандал алай аскер» гафуникай арадал атана. Идан себеб, Урусатдин Империядин чӀавуз КцӀар [[ЦӀал|цIалина]] урусрин балкӀанрал алай аскеррин кьушунрин кӀеретӀар авай. Муькуь алимрин фикирдалди, ''КцӀар'' гаф ''«гъуц»'', ''«кьве сур»'' (кьисадив кьурвал, са мус ятӀа ина кьве лезгидин арада къал акъатнай, абуру сада сад яна кьинай, ахпа абур кьведни ина кучуднай), ''«ксар»'' (дегь алпандин тайифадин тӀвар) гафарикай арадал атанвайди мумкин я. ==Жугърафия== [[ЦӀал|ЦIал]] [[КцӀар район]]дин кьибле пата, [[Къуба район]]дихъ галаз часпара, [[КцӀар вацӀ]]ун кьерел, [[Баку]] шегьердилай 180 км яргъал ала. КцӀарин къвалав [[Фиалка]] тӀвар алай вир гала. ==Тарих== Кцlар [[ЦӀал|цIал]] Урус Чарвилин ч1авуз Къуба вилаятдин къене хьанвай чкарикай сад я. КцӀариз 1930-лагьа йисда Азербайжан Совет Сосиалист Республикадин гьукуматдин патала мухъ (район) ва [[ЦӀал|цIал]] статус ганвай. 1963-65 йисара КцIарин къене [[Хтар|Хт1ар]] [[ЦӀал|цIалини]] хьанад ахпа 1965-лагьа йисдиз ам легъвна Хачмаз мухъ (район) мад хъвуна. ==Агьалияр== Йисариз килигна шегьердин агьалийрин кьадар: {|class="wikitable" style="padding:0;background:#fafafa;border:1px solid #bbb;width:700px;height:70px;text-align:center;font-size:12px;cellspacing=0" |- |'''style="background: bgcolor="#CBD5C4" |'''Йис''' | '''[[1926 йис|1926]]''' | '''[[1939 йис|1939]]''' | '''[[1959 йис|1959]]''' | '''[[1970 йис|1970]]''' | '''[[1979 йис|1979]]''' | '''[[2009 йис|2009]]''' | '''[[2013 йис|2013]]''' |- |'''style="background: bgcolor="#CBD5C4" |'''Агьалияр''' | 2 996 | {{гзаф хьун1}} 4 329 | {{гзаф хьун1}} 7 366 | {{гзаф хьун1}} 11 144 | {{гзаф хьун1}} 12 017 | {{гзаф хьун1}} 16 466 | {{гзаф хьун1}} 17 500 |} <div class="center">'''Урусатдин, СССР-дин ва Азербайжандин агьалияр сиягьдиз къачунин малуматриз килигна КцӀар шегьердин миллетрин состав.'''</div> {| border="1" cellpadding="4" cellspacing="0" style="margin: 10px 0 10px 25px; width:900px; height:20px; background: #fafafa; border: 1px #AAA solid; border-collapse: collapse; font-size: 85%; float: center; text-align:center" |- style="background: #fafafa" |-bgcolor="#CBD5C4" | ''' Йис''' | '''1926 <ref>[http://www.ethno-kavkaz.narod.ru/kuba26.html Кубинский уезд (1926 г.)]</ref>''' | '''1939 <ref>[http://www.ethno-kavkaz.narod.ru/kusary39.html Кусарский район (1939 г.)]</ref>''' | '''1959 <ref>[http://www.ethno-kavkaz.narod.ru/kusary59.html Кусарский район (1959 г.)]</ref>''' | '''1970 <ref>[http://www.ethno-kavkaz.narod.ru/kusary70.html Кусарский район (1970 г.)]</ref>''' | '''1979 <ref>[http://www.ethno-kavkaz.narod.ru/kusary79.html Кусарский район (1979 г.)]</ref>''' |- |align="left"|'''[[лезгияр]]''' |430 (14,4 %) |{{гзаф хьун1}}2 104 (48,6 %) |{{гзаф хьун1}} 4 804 (65,2 %) |{{гзаф хьун1}}8 257 (74,1 %) |{{гзаф хьун1}}9 610 (80 %) |- |align="left"|'''[[азербайжанар]]''' |628 (21 %) |{{гзаф хьун1}}826 (19,1 %) |{{гзаф хьун1}}956 (13 %) |{{гзаф хьун1}}1 413 (12,7 %) |{{гзаф хьун1}}1 444 (12 %) |- |align="left"|'''[[урусар]]'''/ '''[[украинар]]''' |1 634 (54,6 %) |{{тӀимил хьун1}} 1 034 (23,9 %) |{{гзаф хьун1}} 1 050 (14,3 %) |{{тӀимил хьун1}}973 (8,7 %) |{{тӀимил хьун1}}585 (4,9 %) |- |align="left"|'''[[чувудар]]''' |120 (4 %) |{{гзаф хьун1}}241 (5,6 %) |{{тӀимил хьун1}}230 (3,1 %) |{{гзаф хьун1}}313 (2,8 %) |{{тӀимил хьун1}}173 (1,4 %) |- |align="left"|'''вири''' |{{гзаф хьун1}}'''2 996 (100 %)''' |{{гзаф хьун1}}'''4 329 (100 %)''' |{{гзаф хьун1}}'''7 366 (100 %)''' |{{гзаф хьун1}}'''11 144 (100 %)''' |{{гзаф хьун1}}'''12 017 (100 %)''' |} ==Икътисадийят== Шегьерда консерврин, некӀедин ва асфальт гьазурзавай заводар кардик ква. ==Меденийет ва чирвилер== [[1998 йис]]уз КцӀара Гьукуматдин лезги драм театр ахъайнай. [[2006 йис]]уз шегьерда 6 юкьван чирвилерин мектебар кӀвалахзавай, абурукай сад азербайжан вадни урус мектебар тир. Идалайни гъейри, шегьерда мектебдилай вилик гьазурвилер гудай чирвилерин идара, Азербайжандин Гьукуматдин Педагожи Колледж кардик ква. Колледжда азербайжан чӀалан, ингилис чӀалан ва адабийятдин муаллимар ва гьакӀни сифте кьилин мектебрин муаллимар гьазурзава. ==Улакь== ==Идман== Шегьерда са Олимпия Комплекс авазва ва кардик ква. Адла гъерини шегьерда гзаф кьадарда идман залар ва идмандика тIарсар визвай залар авазва. ==Акунаравай - Машгьур инсанар== * [[Хъуьлуьхъ Гъази Мугьаммад]] - лезги имам * [[Аскеров Гьилал]] — лезги шаир ва журналист. * [[Ризванов Ризван Забитан хва]] — машгьур лезги шаир, тариххъан ва таржумахъан. * [[Эфендиев Ярмет Яверан хва]] — лезги шаир ва кхьираг. ==Килигуниз лайих тир чкаяр== Шагьдагъ, Лермонтован кlвал музей ==Эдебийят== * [http://ir.nmu.org.ua/bitstream/handle/123456789/112904/7473ef4328e7ca43214c1d233b92f000.pdf?sequence=1 М. М. Ихилов «Народы лезгинской группы»] {{Webarchive|url=https://web.archive.org/web/20150402140550/http://ir.nmu.org.ua/bitstream/handle/123456789/112904/7473ef4328e7ca43214c1d233b92f000.pdf?sequence=1 |date=2015-04-02 }} == Баянар == {{Баянар}} == ЭлячӀунар == * [http://www.kycap.com/city/history.html КцӀарин сайтунал шегьердин тарихдикай малуматар] {{КцӀар райондин яшамиш жезвай чкаяр}} [[Категория:КцӀар район]] [[Категория:Азербайжандин шегьерар]] [[Категория:Лезги шегьерар]] azd8c2svdg39owxkfknioumsnrwrlkk Хтар 0 656 99905 99867 2026-11-02T13:11:43Z ~2026-58018-65 13315 /* */ 99905 wikitext text/x-wiki {{ЯШЧ2 |тӀвар=ХтIар |статус= Шегьер |вичин чӀалал тӀвар ={{lang-az|Xudat}} |ЯШЧдин статус = |уьлкве = Азербайжан |lat_dir = |lat_deg =41.6302636|lat_min =|lat_sec = |lon_dir = |lon_deg =48.7046256|lon_min =|lon_sec = |CoordAddon = |CoordScale = |гьукуматдин картадин алцум =300 |региондин картадин алцум =0 |райондин картадин алцум =0 |региондин жуьре = |регион = Къуба-Хъачмаздин экономикадин регион |регион таблицада = |райондин жуьре = Муниципал район |район = Хъачмаз район‎ |жемятдин жуьре = Муниципалитет |жемят = |жемят таблицада = |къенепатан паюнар = |кьилин жуьре = |кьил = |бине эцигай тарих = |статус йисалай = [[1950 йис]]алай шегьер я |кьакьанвилин жуьре = |ЯШЧдин кьакьанвал = |климат = |официал чӀал = |майдан = |агьалияр = 15 437 <ref>[http://www.stat.gov.az/source/regions/az/007_2.xls Azərbaycan Respublikasının Dövlət Statistika Komitəsi Xaçmaz rayonu]</ref> |сиягьдиз къачур йис = 2009 |къалинвал = |агломерация = |миллетар = [[азербайжанар]], [[лезгияр]], [[куьрдер]] |динар = [[сунияр|суни]] ва [[шиияр|шии]] - [[мусурманар]] |чпи-чпиз гузвай тӀвар = |сятдин чӀул = +4, +5 |DST = |телефондин код = +994 172 |почтунин индекс = |почтайрин индексар = |автомобилдин код = 27 |идентификатордин жуьре = |цифрадин идентификатор = |Commons-ра категория = |сайт = |сайтдин чӀал = |add2n = Космосдай акунар |add2 = [http://wikimapia.org/#lang=ru&lat=41.630264&lon=48.684626&z=14&m=b www.wikimapia.org] }} '''ХтӀар ''' ({{lang-az|Xudat}}) — хтарар [[сихил]] авай хуьр [[Азербайжан]]дин [[Хъачмаз район]]да авай цlал (гъала, шегьир). Цlалин (гъалайин, шегьердин) статус [[1950 йис]]уз къачунай. ==География== Шегьер [[Азербайжан Республика]]дин кефердинни-рагъэкъечӀдай пата, [[Самур-Девечи аран]]да, [[Хъачмаз район]]дин юкьван пата, райондин кьилин шегьер тир Хъачмаз шегьердилай 20,4 км кефер пата, Баку шегьердилай 184 км яргъал, «[[Худат (станция)|Худат]]» ракьун рекьин станциядал ала. ==Тарих== ЦӀуру-Хтара атанавай "ХтӀарар" сихилди бине ктуна и хуьруьк. == Агьалияр == [[2009 йис]]ан Азербайжан Республикадин агьалияр сиягьдиз къачунин малуматриз килигна, шегьерда 15.437 касди уьмуьр гьалзавай, абурукай: итимар — 7.615 кас, папар — 7.822 кас тир. Йисариз килигна шегьердин агьалийрин кьадар: {|class="wikitable" |- |'''Йис''' ! [[1959 йис|1959]] ! [[1970 йис|1970]] ! [[1979 йис|1979]] ! [[1989 йис|1989]] ! [[2009 йис|2009]] |- |'''Агьалияр, <br> агъзур. кас''' | <span style="color: red; font-weight:bold; font-size: larger;">↗</span>7 068<ref>[http://demoscope.ru/weekly/ssp/ussr59_reg2.php Всесоюзная перепись населения 1959 г.]</ref> | <span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>8 808<ref>[http://demoscope.ru/weekly/ssp/ussr70_reg2.php Всесоюзная перепись населения 1970 г.]</ref> | <span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>9 887<ref>[http://www.ethno-kavkaz.narod.ru/xachmas79.html Всесоюзная перепись населения 1979 г.]</ref> | <span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>10 894<ref>[http://demoscope.ru/weekly/ssp/sng89_reg2.php Всесоюзная перепись населения 1989 г.]</ref> | <span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>15 437 |} === Миллетар === Худат гзафмиллетрин шегьер я. Ина [[азербайжанар]], [[лезгияр]], [[куьрдер]], [[татар]], [[урусар]], [[туьрквер]], [[къарачияр]] хьтин халкьари санал уьмуьр гьалзава. Агьалийрин чӀехи пай азербайжанари туькӀуьрзава. Совет береда шегьерда азербайжанаринни лезгийрин кьадарар саки сад хьиз тиртӀа, гила азербайжанар лезгийрилай саки кьведра пара ава. Лезгийрин тӀимил хьунин себебар, [[Суван Къарабагъдин Республика|Суван Къарабагъдин]] конфликт чӀавуз гзафбурун [[Дагъустан]]диз куьч хьун ва шегьерда амукьай пара кьадарда лезги хзанар ассимиляция хьана азербайжанариз элкъуьн я. Ахьтинбурун паспортра миллет къалурзавай цӀарцӀел ''«азербайжанви»'' кхьенвайди я. Шегьерда, паспортра ''«азербайжанви»'' кхьенвай «михьи» азербайжанвияр саки авайди туш. Азербайжанвияр хьиз къалурнавайбурун гзафни-гзаф пай тарихдин къене азербайжанлашмиш хьанвай татар, куьрдер, туьрквер, лезгияр, цыганар ва маса бицӀи халкьар я. Абуруз чпин улу бубаяр маса халкьар тирди чизва, амма чӀал ва гьа миллетдиз талукьвилин кьатӀун тамамдаказ квахьнава. Хайи чӀал са гьалда хвенвай тек сад тир халкь — лезгияр я. Амма а лезгийрин са паюнин [[лезги чӀал]]ан чирвилер акьван усал я хьи, абур лезги чӀаланни азербайжан чӀалан акахьунал рахазва. И акахьай чӀалан азербайжанарни гъавурда акьазва. Азербайжан агьалидин кьуьзуь несилар лезги чӀалан гъавурда акьазва, гзафбурувай адал рахазни жезва. Шегьерда цыганри компакт шикилда уьмуьр гьалзавай Къарачи мягьле ава. Шегьерда азербайжан чӀал ва культура йигиндиз вилик физвай береда маса халкьарин, иллаки лезгийрин чӀал ва культура кьулухъ амукьзава. Шегьердин мектебра тарсар анжах азербайжандал тухузвайди я. Лезги хзанра, «къвезмай уьмуьрда четин тежедайвал ва мектебра сад-садахъ галаз рахаз регьят жедайвал» аялдиз сифте лезги чӀал ваъ, азербайжан чӀал чирзава. Ахьтин хзанрин кьадар йисандивай-йисуз пара жезва. Гьавиляй маса халкьар азербайжанарин арада цӀрана терг жезва. Гилан гьалар и камаралди давам хьайитӀа са-кьве несил алатайла лезгиярни татринни куьрдерин гелеваз фида, шегьерда лезгийрикай амукьдайди са тӀвар ва азербайжанариз элкъвенвай жегьил несилар жеда. <center>'''Урусатдин, СССР-дин ва Азербайжандин агьалияр сиягьдиз къачунин малуматриз килигна Худат шегьердин миллетрин состав.'''</center> {| class="wikitable" !rowspan="2"|Халкь||colspan="2"|<center>1959 йис<ref>[http://www.ethno-kavkaz.narod.ru/xudat59.html Худат район (1959 й.)]</ref>||colspan="2"|<center>1970 йис<ref>[http://www.ethno-kavkaz.narod.ru/xachmas70.html Хъачмаз район (1970 й.)]</ref>||colspan="2"|<center>1979 йис<ref>[http://www.ethno-kavkaz.narod.ru/xachmas79.html Хъачмаз район (1979 й.)]</ref> |- ! Векилрин кьадар ! Пай<br>% ! Векилрин кьадар ! Пай<br>% ! Векилрин кьадар ! Пай<br>% |- |'''[[Азербайжанар]]''' |3 282||'''32,0 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>3 970||'''45,1 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>5 409||'''54,7 %''' |- |'''[[Лезгияр]]''' |2 494||'''24,3 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>2 734||'''31,0 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>3 205||'''32,4 %''' |- |'''[[Урусар]]''' |3 546||'''34,6 %''' |<span style="color: red; font-weight:bold; font-size: larger;">↘</span>1 137||'''12,9 %''' |<span style="color: red; font-weight:bold; font-size: larger;">↘</span>733||'''7,4 %''' |- |'''[[Куьрдер]]''' |240||'''2,3 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>588||'''6,7 %''' |<span style="color: red; font-weight:bold; font-size: larger;">↘</span>417||'''4,2 %''' |- |'''[[Эрменияр]]''' |80||'''0,8 %''' |<span style="color: red; font-weight:bold; font-size: larger;">↘</span>57||'''0,6 %''' |<span style="color: red; font-weight:bold; font-size: larger;">↘</span>17||'''0,2 %''' |- |'''[[Чувудар]]''' |10||'''0,1 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>40||'''0,5 %''' |<span style="color: #0c0; font-weight:bold; font-size: larger;">↗</span>37||'''0,4 %''' |- |'''[[Татарар]]''' | — || — |20||'''0,2 %''' |<span style="color: red; font-weight:bold; font-size: larger;">↘</span>15||'''0,2 %''' |- |'''[[Татар]]''' |16||'''0,1 %''' |3||'''0,1 %''' | — || — |- |'''[[Аварар]]''' | — || — |6||'''0,1 %''' | — || — |- |'''[[Гуржияр]]''' |5||'''0,1 %''' |6||'''0,2 %''' |4||'''0,2 %''' |- |'''Вири санлай''' |7 068||'''100 %''' |8 808||'''100 %''' |9 887||'''100 %''' |- |} ==Экономика== == Баянар == {{Баянар}} == ЭлячӀунар == {{Хъачмаз райондин яшамиш жезвай чкаяр}} [[Категория:Хъачмаз район]] [[Категория:Лезги шегьерар]] [[Категория:Азербайжандин шегьерар]] dedt6ymje705vncxy4mcisrgcxn6t8i MediaWiki:Vector.css 8 1953 99910 16551 2026-11-02T19:41:27Z Maintenance script 3796 Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup) 99910 css text/css /* Размещённый здесь CSS будет применяться к векторной теме оформления */ /* {Link FA} */ .portal li.GA { background: url('//upload.wikimedia.org/wikipedia/commons/6/6f/QS_blue_star_small.png') right top no-repeat; margin-right: 10px !important; } .portal li.FA { background: url('//upload.wikimedia.org/wikipedia/commons/3/33/Small_skew_star.gif') right top no-repeat; margin-right: 10px !important; } .portal li.FL { background: url('//thumb.wikimedia.org/wikipedia/commons/thumb/0/02/Purple_star_unboxed.svg/11px-Purple_star_unboxed.svg.png') right top no-repeat; margin-right: 10px !important; } /* Topicons */ .topicon { position: absolute; top: -2em; right: 0; } 4yplijksgg88qvf3c2mklxmjlg7a9wx MediaWiki:Monobook.css 8 1954 99908 74042 2026-11-02T19:41:24Z Maintenance script 3796 Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup) 99908 css text/css /* Размещённый здесь CSS будет применяться к теме оформления Monobook */ /*{Link FA}*/ .portlet li.FA {list-style-image:url('//upload.wikimedia.org/wikipedia/en/d/d4/Monobook-bullet-star.png')} .portlet li.FL {list-style-image:url('//thumb.wikimedia.org/wikipedia/commons/thumb/0/02/Purple_star_unboxed.svg/9px-Purple_star_unboxed.svg.png')} .portlet li.GA {list-style-image:url('//thumb.wikimedia.org/wikipedia/commons/thumb/6/6f/QS_blue_star_small.png/9px-QS_blue_star_small.png')} /*compat. standard bullet*/ .portlet li { list-style-image: url('//upload.wikimedia.org/wikipedia/commons/1/18/Monobook-bullet.png') } /*Topicons*/ .topicon { position: absolute; top: 10px; right: 10px; z-index: 10; } #coordinates { position: absolute; top: 3.7em; right: 9em; font-size: 11px; white-space: nowrap; } rawa4slr3v4m3bw61mh3zrjon26ierm MediaWiki:Gadget-wefcore.js 8 8234 99906 74376 2026-11-02T19:41:21Z Maintenance script 3796 Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup) 99906 javascript text/javascript /** * Those JavaScript classes are main core of WE-Framework to edit Wikidata using * JQuery dialogs. They provide classes to edit snak values, snaks, claims, and * claim groups (of the same property). For the examples how to use those * classes see "WEF_ExternalLinks.js" and "WEF_PersonEditor.js". * * @see https://github.com/vlsergey/WE-Framework * @author vlsergey */ window.wef_Editors_i18n_en = { actionAnalyzeChanges: 'Collecting and analyzing changes to entity', actionNoChangesPurge: 'No changes found, purge and refresh current page', actionObtainCentralAuthToken: 'Get new global auth token', actionObtainEditToken: 'Get edit token', actionUpdateEntity: 'Saving changes in entity (update and create statements)', actionRemoveClaims: 'Saving changes in entity (remove statements)', buttonSelectSnakType: 'select snak type', buttonAddClaim: 'add claim', buttonRemoveClaim: 'remove claim', buttonAddQualifier: 'add qualifier', buttonRemoveQualifier: 'remove qualifier', buttonUrlNavigate: 'open specified URL', buttonCreateOrEdit: 'create or edit wikidata item', buttonCreateOrEditPrefixCreate: 'create as: ', buttonCreateOrEditPrefixEdit: 'edit as: ', buttonOnWikidata: 'open specified wikidata item on wikidata website', checkboxShowJulian: 'show in Julian calendar?', checkboxShowJulianTitle: 'when displaying the date show in julian calendar. This option does not change the input format or the value stored', confirmDeleteClaim: 'Remove the value of property «{label}»?', dialogAnalyzeChangesTitle: 'Analyze changes...', dialogSaveChangesTitle: 'Saving changes to Wikidata...', errorAnalyzeChanges: 'Unable to collect and analyze changes', errorObtainCentralAuthToken: 'Unable to obtain new global auth token', errorObtainEditToken: 'Unable to obtain edit token', errorUpdateEntity: 'Unable to update entity', errorRemoveClaims: 'Unable to remove outdated statements from entity', inputGlobeLatitudeLabel: 'Latitude', inputGlobeLatitudeTitle: 'a latitude (decimal, no default, 9 digits after the dot and two before, signed)', inputGlobeLongitudeLabel: 'Longitude', inputGlobeLongitudeTitle: 'a longitude (decimal, no default, 9 digits after the dot and three before, signed)', inputGlobeAltitudeLabel: 'Altitude', inputGlobeAltitudeTitle: '', inputGlobePrecisionLabel: 'Precision', inputGlobePrecisionTitle: 'a precision (decimal, representing degrees of distance, defaults to 0, 9 digits after the dot and three before, unsigned, used to save the precision of the representation)', inputGlobeGlobeLabel: 'Globe', inputGlobeGlobeTitle: 'a coordinate system or globe (identified by an URI, defaults to the Earth, which means WGS84). Any such geodesic system must imply the globe for which it is used (and should be displayed as simply the globe in most cases)', inputQuantityUnitLabel: 'unit', inputQuantityUnitTitle: '', inputQuantityLowerBoundLabel: 'lower bound', inputQuantityLowerBoundTitle: '', inputQuantityAmountLabel: 'amount', inputQuantityAmountTitle: '', inputQuantityUpperBoundLabel: 'upper bound', inputQuantityUpperBoundTitle: '', inputQuantityModeExact: 'exact', inputQuantityModePlusMinus: 'plus-minus', inputQuantityModeOther: 'other', inputTimeAsGregorianLabel: 'Date in Gregorian calendar model', inputTimeAsJulianLabel: 'Date in Julian calendar model', inputTimeTimeLabel: 'Time (ISO notation)', inputTimeTimeTitle: 'Date and time in ISO notation, including. E.g. "+1994-01-01T00:00:00Z"', inputTimeTimeZoneLabel: 'Timezone (minutes)', inputTimeTimeZoneTitle: 'The time zone offset against UTC, in minutes. May be given as an integer or string literal.', inputTimeCalendarModelLabel: 'Calendar model', inputTimeCalendarModelTitle: 'A calendar model, such as gregorian or julian', inputTimePrecisionLabel: 'Precision', inputTimePrecisionTitle: 'To what unit is the given date/time significant?', labelLabels: 'Label, description and aliases', labelLabel: 'Label', labelDescription: 'Description', labelAliases: 'Aliases', rankDeprecatedValue: 'deprecated', rankDeprecatedTitle: 'used for a statement that contains information that may not be considered reliable or that is known to include errors. (For example, a statement that documents a wrong population figure that was published in some historic document. In this case the statement is not wrong – the historic document that is given as a reference really made the erroneous claim – but the statement should not be used in most cases.)', rankNormalValue: 'normal', rankNormalTitle: 'used for a statement that contains relevant information that is believed to be correct, but may be too extensive to be shown by default. (For example, historic population figures for Berlin over the course of many years.)', rankPreferredValue: 'preferred', rankPreferredTitle: 'used for a statement with the most important and most up-to-date information. Such a statement will be shown to all users and will be displayed in Wikipedia infoboxes by default. (For example, the most recent population figures for Berlin.)', snakTypeValue: 'custom value', snakTypeValueTitle: 'is a marker for when there is a known value for the property that can be specified. ' + 'This is the default snak type when creating a snak/claim/statement.', snakTypeNoValue: 'no value', snakTypeNoValueTitle: 'is a marker for when there certainly is no value for the property (example: if a human has no children, the corresponding item would receive this marker for ребёнок (P40)).' + ' Assigning the "no value" marker is a proper statement and is different to an item lacking a property.' + ' Latter implicates that it is unknown whether the property has no or some value (example: a missing human that may be dead or alive cannot be assigned дата смерти (P570) while, for consistency, a living human should feature дата смерти (P570) with the no value marker applied, clearly denoting that the human is not dead).', snakTypeSomeValue: 'unknown value', snakTypeSomeValueTitle: ' is a marker for when there is some value but the exact value is not known for the property. ' + '"Some value" means that there is nothing known for the value except that it should exist and not imply a negation of the claim (example: if the date of a human\'s death is completely unknown the item would receive this marker for death date (P570), denoting that the human is, in fact, dead — however, with the date of death being unknown).', timePrecision0: '1 Gigayear', timePrecision1: '100 Megayears', timePrecision2: '10 Megayears', timePrecision3: 'Megayear', timePrecision4: '100 Kiloyears', timePrecision5: '10 Kiloyears', timePrecision6: 'Kiloyear', timePrecision7: '100 years', timePrecision8: '10 years', timePrecision9: 'year', timePrecision10: 'month', timePrecision11: 'day', timePrecision12: 'hour', timePrecision13: 'minute', timePrecision14: 'second', timePrecisionOther: 'other', sourcesDialogTitle: 'View and edit sources for claim — WE-Framework', sourcesButtonUpdateLabelsText: 'Update labels', sourcesButtonUpdateLabelsLabel: 'Redownload properties, qualificator and objects labels and descriptions from Wikidata', sourcesButtonAddText: 'Add', sourcesButtonAddLabel: 'Add new reference to the list', sourcesButtonCloseText: 'Close', sourcesButtonCloseLabel: 'Close the dialog', sourcesLabelAddUsedReferences: 'Quick add recently used sources: ', }; window.wef_Editors_i18n_ru = { actionAnalyzeChanges: 'Сбор и анализ изменений в элементе', actionNoChangesPurge: 'Изменения не найдены, перезагрузка текущей страницы', actionObtainCentralAuthToken: 'Получение нового токена централизованной аутентификации', actionObtainEditToken: 'Получение токена редактирования', actionUpdateEntity: 'Сохранение изменений в элемент (обновление и создание утверждений)', actionRemoveClaims: 'Сохранение изменений в элемент (удаление утверждений)', buttonSelectSnakType: 'выбрать тип значения', buttonAddClaim: 'добавить утверждение', buttonRemoveClaim: 'удалить утверждение', buttonAddQualifier: 'добавить квалификатор', buttonRemoveQualifier: 'удалить квалификатор', buttonUrlNavigate: 'открыть указанный URL', buttonCreateOrEdit: 'создать или редактировать элемент Викиданных', buttonCreateOrEditPrefixCreate: 'создать: ', buttonCreateOrEditPrefixEdit: 'редактировать: ', buttonOnWikidata: 'открыть указанный элемент Викиданных на сайте Викиданных', checkboxShowJulian: 'показывать по Юлианскому календарю', checkboxShowJulianTitle: 'при отображении даты включать режим отображения по юлинскому календарю. Данная опция не влияет на формат ввода или хранения.', confirmDeleteClaim: 'Удалить значение свойства «{label}»?', dialogAnalyzeChangesTitle: 'Анализ изменений...', dialogSaveChangesTitle: 'Сохранение изменений на Викиданных', errorAnalyzeChanges: 'Произошла ошибка при анализе изменений', errorObtainCentralAuthToken: 'Произошла ошибка при получении нового токена глобальной аутентификации', errorObtainEditToken: 'Произошла ошибка при получении нового токена редактирования', errorUpdateEntity: 'Произошла ошибка при сохранении изменений в элемент', errorRemoveClaims: 'Произошла ошибка при удалении устаревших утверждений из элемента', inputGlobeLatitudeLabel: 'Широта', inputGlobeLatitudeTitle: 'широта (десятичное число, значение по умолчанию не задано, 9 цифр после запятой и два до; знаковое)', inputGlobeLongitudeLabel: 'Долгота', inputGlobeLongitudeTitle: 'долгота (десятичное число, значение по умолчанию не задано, 9 цифр после запятой и три до; знаковое)', inputGlobeAltitudeLabel: 'Высота', inputGlobeAltitudeTitle: 'Высота (десятичное число, значение по умолчанию не задано, 9 цифр после запятой и два до; знаковое)', inputGlobePrecisionLabel: 'Точность', inputGlobePrecisionTitle: 'точность (десятичное число, representing degrees of distance, значение по умолчанию 0, 9 цифр после запятой и три до; знаковое, используется для указания точности представления георафической координаты)', inputGlobeGlobeLabel: 'Глобус', inputGlobeGlobeTitle: 'координатная система или глобус (указывается идентификатором, по умолчанию Земля, т. е. WGS84)', inputQuantityUnitLabel: 'единица', inputQuantityUnitTitle: '', inputQuantityLowerBoundLabel: 'нижняя граница', inputQuantityLowerBoundTitle: '', inputQuantityAmountLabel: 'количество', inputQuantityAmountTitle: '', inputQuantityUpperBoundLabel: 'верхняя граница', inputQuantityUpperBoundTitle: '', inputQuantityModeExact: 'точно', inputQuantityModePlusMinus: 'плюс-минус', inputQuantityModeOther: 'другое', inputTimeAsGregorianLabel: 'дата по григорианскому календарю (новый стиль)', inputTimeAsJulianLabel: 'дата по юлианскому календарю (старый стиль)', inputTimeTimeLabel: 'Дата и время (ISO-нотация)', inputTimeTimeTitle: 'Дата и время в ISO-нотации, т. е. «+1994-01-01T00:00:00Z» по григорианскому календарю', inputTimeTimeZoneLabel: 'Часовой пояс (в минутах)', inputTimeTimeZoneTitle: 'Сдвиг часового пояса относительно UTC, в минутах', inputTimePrecisionLabel: 'Точность', inputTimePrecisionTitle: 'Какая наиболее точная значая единица для данного значения?', inputTimeCalendarModelLabel: 'Календарь для отображения', inputTimeCalendarModelTitle: 'Календарь, например, юлианский или григорианский', labelLabels: 'Метка, описание и синонимы', labelLabel: 'Метка', labelDescription: 'Описание', labelAliases: 'Также известен как', rankDeprecatedValue: 'нерекомендуемый', rankDeprecatedTitle: 'используется для утверждений, содержащих информацию, которую нельзя считать надёжной или которая содержит известные ошибки. (Например, утверждение сообщает о неверной численности населения, опубликованной в некоем историческом документе. В этом случае утверждение не является ложным — в историческом документе, указанном в качестве источника, действительно было сделано ошибочное заявление — но такое утверждение в большинстве случаев не стоит использовать.)', rankNormalValue: 'нормальный', rankNormalTitle: ' используется для утверждений, содержащих релевантную информацию, которая считается верной, но которой, возможно, слишком много для отображения по умолчанию. (Например, измерения исторической численности населения Берлина на протяжении множества лет.)', rankPreferredValue: 'предпочтительный', rankPreferredTitle: 'используется для утверждений с наиболее важной и наиболее актуальной информацией. Такое утверждение будет показываться всем участникам и будет отображаться в шаблонах-карточках Википедии по умолчанию. (Например, самые последние сведения о численности населения Берлина.)', snakTypeValue: 'своё значение', snakTypeNoValue: 'значение не задано', snakTypeSomeValue: 'неизвестное значение', timePrecision0: 'гигагод', timePrecision1: '100 мегалет', timePrecision2: '10 мегалет', timePrecision3: 'мегагод', timePrecision4: '100 килолет', timePrecision5: '10 килолет', timePrecision6: 'килогод', timePrecision7: 'век', timePrecision8: '10 лет', timePrecision9: 'год', timePrecision10: 'месяц', timePrecision11: 'день', timePrecision12: 'час', timePrecision13: 'минута', timePrecision14: 'секунда', timePrecisionOther: 'другое', sourcesDialogTitle: 'Просмотр и редактирование источников для утверждения — WE-Framework', sourcesButtonUpdateLabelsText: 'Обновить названия', sourcesButtonUpdateLabelsLabel: 'Заново загрузить названия полей, квалификаторов и объектов с Викиданных', sourcesButtonAddText: 'Добавить', sourcesButtonAddLabel: 'Добавить новую сноску на источник в список', sourcesButtonCloseText: 'Закрыть', sourcesButtonCloseLabel: 'Закрыть диалоговое окно', sourcesLabelAddUsedReferences: 'Быстрое добавление недавно использованных источников: ', }; window.WEF_Editors_i18n = function() { this.htmlInProgress = '<img alt="⌚" src="//thumb.wikimedia.org/wikipedia/commons/thumb/6/6a/Pictogram_voting_wait.svg/17px-Pictogram_voting_wait.svg.png" srcset="//thumb.wikimedia.org/wikipedia/commons/thumb/6/6a/Pictogram_voting_wait.svg/26px-Pictogram_voting_wait.svg.png 1.5x, //thumb.wikimedia.org/wikipedia/commons/thumb/6/6a/Pictogram_voting_wait.svg/34px-Pictogram_voting_wait.svg.png 2x" data-file-width="250" data-file-height="250" height="17" width="17">'; this.htmlSuccess = '<img alt="✔" src="//thumb.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/15px-Yes_check.svg.png" srcset="//thumb.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/23px-Yes_check.svg.png 1.5x, //thumb.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/30px-Yes_check.svg.png 2x" data-file-width="600" data-file-height="600" height="15" width="15">'; this.htmlFailure = '<img alt="×" src="//thumb.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/16px-Red_x.svg.png" srcset="//thumb.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/24px-Red_x.svg.png 1.5x, //thumb.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/32px-Red_x.svg.png 2x" data-file-width="600" data-file-height="600" height="16" width="16">'; this.htmlNotNeeded = '<img alt="(=)" src="//thumb.wikimedia.org/wikipedia/commons/thumb/2/25/Pictogram_voting_neutral.svg/15px-Pictogram_voting_neutral.svg.png" srcset="//thumb.wikimedia.org/wikipedia/commons/thumb/2/25/Pictogram_voting_neutral.svg/23px-Pictogram_voting_neutral.svg.png 1.5x, //thumb.wikimedia.org/wikipedia/commons/thumb/2/25/Pictogram_voting_neutral.svg/30px-Pictogram_voting_neutral.svg.png 2x" data-file-width="250" data-file-height="250" height="15" width="15">'; this.summary = 'via [[:w:ru:ВП:WE-F|WE-Framework gadget]] from ' + mw.config.get( 'wgDBname' ); WEF_Utils.localize( this, 'wef_Editors_i18n_' ); }; /* Some commons i18n strings for all editors */ window.wef_AnyEditor_i18n_en = { dialogButtonUpdateLabelsText: 'Update labels', dialogButtonUpdateLabelsLabel: 'Redownload properties, qualificator and objects labels and descriptions from Wikidata', dialogButtonSaveText: 'Save', dialogButtonSaveLabel: 'Close the dialog and save all changes to Wikidata', dialogButtonCancelText: 'Cancel', dialogButtonCancelLabel: 'Close the dialog and discard all changes (do not save)', dialogTitle: 'WE-Framework', dialogTitleNewElement: '(new item)', fieldsetGeneral: 'general', groupGeneral: 'general', errorLoadingWikidata: 'Unable to load element data from Wikidata', statusLoadingWikidata: 'Loading element data from Wikidata', }; window.wef_AnyEditor_i18n_fr = { dialogButtonUpdateLabelsText: 'Mettre à jour les libellés', dialogButtonUpdateLabelsLabel: 'Recharger les labels et descriptions des propriétés, qualificatifs et objets', dialogButtonSaveText: 'Enregistrer', dialogButtonSaveLabel: 'Fermer la fenêtre en enregistrant les modifications sur Wikidata', dialogButtonCancelText: 'Annuler', dialogButtonCancelLabel: 'Fermer la fenêtre sans enregistrer', dialogTitle: 'WE-Framework', fieldsetGeneral: 'général', groupGeneral: 'général', errorLoadingWikidata: 'Échec du chargement des données de Wikidata', statusLoadingWikidata: 'Chargement des données de Wikidata', }; window.wef_AnyEditor_i18n_ru = { dialogButtonUpdateLabelsText: 'Обновить названия', dialogButtonUpdateLabelsLabel: 'Заново загрузить названия полей, квалификаторов и объектов с Викиданных', dialogButtonSaveText: 'Сохранить', dialogButtonSaveLabel: 'Закрыть окно и сохранить все изменения в Викиданных', dialogButtonCancelText: 'Отмена', dialogButtonCancelLabel: 'Закрыть окно и отменить все изменения (не сохранять)', dialogTitle: 'WE-Framework', dialogTitleNewElement: '(новый элемент)', fieldsetGeneral: 'основное', groupGeneral: 'основное', errorLoadingWikidata: 'Невозможно загрузить информацию с Викиданных', statusLoadingWikidata: 'Загружаем данные элемента с Викиданных', }; /** @const */ WEF_RANK_PREFERRED = 'preferred'; /** @const */ WEF_RANK_NORMAL = 'normal'; /** @const */ WEF_RANK_DEPRECATED = 'deprecated'; /** * @typedef WEF_Entity * @type {object} * @property {string} id * @property {string} type * @property {object} claims */ /** * @typedef WEF_Claim * @type {object} * @property {string} id * @property {WEF_Snak} mainsnak * @property {string} type * @property {string} rank */ /** * @typedef WEF_Snak * @type {object} * @property {string} snaktype * @property {string} property * @property {string} datatype * @property {object} datavalue */ /** * @param {WEF_Definition} * args * @class */ WEF_Definition = function( args ) { /** @type {string} */ this.code = args.code; /** @type {string} */ this.datatype = 'string'; /** @type {string} */ this.label = undefined; /** @type {string} */ this.labelPrefix = undefined; /** @type {function} */ this.normalize = undefined; /** @type {object} */ this.check = undefined; /** @type {function} */ this.url = undefined; /** @type {WEF_Definition[]} */ this.qualifiers = undefined; $.extend( this, args ); }; window.WEF_Definition = WEF_Definition; WEF_Utils = function() { // no members }; window.WEF_Utils = WEF_Utils; WEF_Utils.appendToNamedMap = function( element, mapName, key, obj ) { "use strict"; if ( typeof element === 'undefined' ) { throw new Error( 'Illegal argument: element is undefined' ); } if ( typeof element[mapName] === 'undefined' ) { element[mapName] = {}; } if ( typeof element[mapName][key] === 'undefined' ) { element[mapName][key] = []; } element[mapName][key].push( obj ); }; WEF_Utils.assertCorrectEntityId = function( entityId ) { if ( !WEF_Utils.isCorrectEntityId( entityId ) ) { throw new Error( 'Incorrect entity ID: ' + entityId ); } }; WEF_Utils.convertGregorianToJulian = function( year, month, day ) { "use strict"; return WEF_Utils._convertJulianDayToJulian( WEF_Utils._convertGregorianToJulianDay( Number( year ), Number( month ), Number( day ), true ) ); }; WEF_Utils._convertGregorianToJulianDay = function( year, month, day, fixNoon ) { "use strict"; var a = ( 1721425.5 - 1 ); var b = ( 365 * ( year - 1 ) ); var c = Math.floor( ( year - 1 ) / 4 ); var d = ( -Math.floor( ( year - 1 ) / 100 ) ); var e = Math.floor( ( year - 1 ) / 400 ); var f = Math.floor( ( ( ( 367 * month ) - 362 ) / 12 ) + ( ( month <= 2 ) ? 0 : ( WEF_Utils._isLeapGregorianYear( year ) ? -1 : -2 ) ) + day ); return a + b + c + d + e + f + ( fixNoon ? 0.5 : 0 ); }; WEF_Utils._convertJulianDayToGregorian = function( julianDay ) { "use strict"; var wjd = Math.floor( julianDay - 0.5 ) + 0.5; var depoch = wjd - 1721425.5; var quadricent = Math.floor( depoch / 146097 ); var dqc = WEF_Utils._mod( depoch, 146097 ); var cent = Math.floor( dqc / 36524 ); var dcent = WEF_Utils._mod( dqc, 36524 ); var quad = Math.floor( dcent / 1461 ); var dquad = WEF_Utils._mod( dcent, 1461 ); var yindex = Math.floor( dquad / 365 ); var year = ( quadricent * 400 ) + ( cent * 100 ) + ( quad * 4 ) + yindex; if ( !( ( cent == 4 ) || ( yindex == 4 ) ) ) { year++; } var yearday = wjd - WEF_Utils._convertGregorianToJulianDay( year, 1, 1, false ); var leapadj = ( ( wjd < WEF_Utils._convertGregorianToJulianDay( year, 3, 1, false ) ) ? 0 : ( WEF_Utils._isLeapGregorianYear( year ) ? 1 : 2 ) ); var month = Math.floor( ( ( ( yearday + leapadj ) * 12 ) + 373 ) / 367 ); var day = ( wjd - WEF_Utils._convertGregorianToJulianDay( year, month, 1, false ) ) + 1; return new Array( year, month, WEF_Utils._floor2( day ) ); }; WEF_Utils._convertJulianDayToJulian = function( julianDay ) { "use strict"; var b = 0; var c = julianDay + 32082; var d = WEF_Utils._floor2( ( 4 * c + 3 ) / 1461 ); var e = c - WEF_Utils._floor2( 1461 * d / 4 ); var m = WEF_Utils._floor2( ( 5 * e + 2 ) / 153 ); var day = e - WEF_Utils._floor2( ( 153 * m + 2 ) / 5 ) + 1; var month = m + 3 - 12 * WEF_Utils._floor2( m / 10 ); var year = 100 * b + d - 4800 + WEF_Utils._floor2( m / 10 ); return new Array( year, month, day ); }; WEF_Utils.convertJulianToGregorian = function( year, month, day ) { "use strict"; return WEF_Utils._convertJulianDayToGregorian( WEF_Utils._convertJulianToJulianDay( Number( year ), Number( month ), Number( day ) ) ); }; WEF_Utils._convertJulianToJulianDay = function( year, month, day ) { "use strict"; var a = WEF_Utils._floor2( ( 14 - month ) / 12 ); var y = year + 4800 - a; var m = month + 12 * a - 3; return day + WEF_Utils._floor2( ( 153 * m + 2 ) / 5 ) + 365 * y + WEF_Utils._floor2( y / 4 ) - 32083; }; WEF_Utils.createWikidataItem = function( itemData ) { var updates = new WEF_Updates( null ); updates.data = itemData; return WEF_Utils.update( updates ); }; WEF_Utils.fillSelectWithMonthes = function( jSelect ) { "use strict"; for ( var i = 1; i <= 12; i++ ) { var option = $( document.createElement( 'option' ) ); option.attr( 'value', i ); option.text( mw.config.get( 'wgMonthNames' )[i] ); jSelect.append( option ); } jSelect.val( -1 ); }; WEF_Utils._floor2 = function( a ) { "use strict"; if ( a >= 0 ) { return Math.floor( a ); } else { return Math.ceil( a ); } }; /** @returns {string} */ WEF_Utils.formatCentury = function( century ) { "use strict"; return WEF_Utils.formatDate( century * 100 ); }; /** @returns {string} */ WEF_Utils.formatDate = function( year, month, day ) { "use strict"; var time; if ( year >= 0 ) { time = '+' + year; } else { time = '-' + ( -year ); } time += '-'; if ( typeof month !== 'undefined' ) { time += ( '00' + month ).substr( -2, 2 ); } else { time += '01'; } time += '-'; if ( typeof day !== 'undefined' ) { time += ( '00' + day ).substr( -2, 2 ); } else { time += '01'; } time += 'T00:00:00Z'; return time; }; WEF_Utils.formatQuantity = function( value ) { "use strict"; if ( Number( value ) > 0 ) { return '+' + Number( value ); } else { return '' + Number( value ); } }; WEF_Utils.formatValueRemotely = function( datatype, datavalue, span ) { "use strict"; var prefix; if ( !WEF_Utils.isWikidata() ) { prefix = '//www.wikidata.org/w/api.php' // + '?origin=' + encodeURIComponent( location.protocol + mw.config.get( 'wgServer' ) ) // + '&format=json'; // } else { prefix = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php' // + '?format=json'; } $.ajax( { type: 'POST', url: prefix // + '&action=wbformatvalue' // + '&generate=' + encodeURIComponent( "text/html" ), data: { datatype: datatype, datavalue: JSON.stringify( datavalue ), uselang: WEF_Utils.getDefaultLanguageCode(), }, error: function( jqXHR, textStatus, errorThrown ) { // too bad :-( console.log( "Unable to call 'wbformatvalue'" ); console.log( textStatus ); console.log( errorThrown ); }, success: function( response ) { if ( response.error ) { console.log( "Unable to call 'wbformatvalue': " + response.error.info ); return; } var result = response.result; if ( typeof result === 'undefined' ) { console.log( "Unable to call 'wbformatvalue': no result" ); return; } // we assume Wikidata is trusted source :-) span.html( result ); }, } ); }; WEF_Utils.getDefaultLanguageCode = ( function() { var defaultLanguageCode; return function() { "use strict"; if ( WEF_Utils.isEmpty( defaultLanguageCode ) ) { defaultLanguageCode = mw.config.get( 'wgUserLanguage' ); if ( WEF_Utils.isEmpty( defaultLanguageCode ) ) { defaultLanguageCode = mw.config.get( 'wgContentLanguage' ); if ( WEF_Utils.isEmpty( defaultLanguageCode ) ) { defaultLanguageCode = 'en'; } } } return defaultLanguageCode; }; } )(); WEF_Utils.getEntityIdFromClaim = function( claim ) { if ( typeof claim == 'undefined' ) return; return WEF_Utils.getEntityIdFromSnak( claim.mainsnak ); }; WEF_Utils.getEntityIdFromSnak = function( snak ) { if ( typeof snak === 'undefined' ) return; return WEF_Utils.getEntityIdFromDatavalue( snak.datavalue ); }; WEF_Utils.getEntityIdFromDatavalue = function( datavalue ) { if ( typeof datavalue === 'undefined' // || typeof datavalue.value === 'undefined'// || typeof datavalue.value['entity-type'] === 'undefined'// || typeof datavalue.value['numeric-id'] === 'undefined'// ) return; var entityType = datavalue.value['entity-type']; var numericId = datavalue.value['numeric-id']; switch ( entityType ) { case 'property': return 'P' + numericId; case 'item': return 'Q' + numericId; default: throw new Error( "Unknown entity type: " + entityType ); } }; /** @return {string} */ WEF_Utils.getEntityId = function() { "use strict"; // TODO: add check if ( WEF_Utils.isWikidata() ) { return mw.config.get( 'wgTitle' ); } else { return mw.config.get( 'wgWikibaseItemId' ); } }; WEF_Utils.getFirstObjectKey = function( obj ) { "use strict"; return Object.keys( obj )[0]; }; WEF_Utils.getFirstObjectValue = function( obj ) { "use strict"; return obj[WEF_Utils.getFirstObjectKey( obj )]; }; /** @returns {string} */ WEF_Utils.getWikidataApiPrefix = function() { "use strict"; if ( mw.config.get( 'wgSiteName' ) === 'Wikidata' ) { return mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php' + '?format=json'; } else { return '//www.wikidata.org/w/api.php' + '?origin=' + encodeURIComponent( location.protocol + mw.config.get( 'wgServer' ) ) + '&format=json'; } }; WEF_Utils.isCorrectEntityId = function( entityId ) { return !WEF_Utils.isEmpty( entityId ) && /^[PQ]\d+$/.test( entityId ); }; WEF_Utils.isEmpty = function( obj ) { return ( !obj || $.trim( obj ) === "" ); }; WEF_Utils._isLeapGregorianYear = function( year ) { "use strict"; return ( ( year % 4 ) === 0 ) && ( !( ( ( year % 100 ) === 0 ) && ( ( year % 400 ) !== 0 ) ) ); }; /** @returns {Boolean} */ WEF_Utils.isWikidata = function() { "use strict"; return mw.config.get( 'wgSiteName' ) === 'Wikidata'; }; WEF_Utils.localize = function( targetObject, globalVariablesPrefix ) { "use strict"; var languages = [ 'ru', 'en', mw.config.get( 'wgContentLanguage' ), mw.config.get( 'wgUserLanguage' ) ]; $.each( languages, function( i, lang ) { if ( window[globalVariablesPrefix + lang] ) { $.extend( targetObject, window[globalVariablesPrefix + lang] ); } } ); }; WEF_Utils.mockEntityWithType = /** * @param {String} * typeEntityId */ function( typeEntityId ) { WEF_Utils.assertCorrectEntityId( typeEntityId ); return { "claims": { "P31": [ { "mainsnak": WEF_Utils.newWikibaseItemSnak( "P31", "item", Number( typeEntityId.substr( 1 ) ) ), "type": "statement", "rank": "normal", } ] } }; }; WEF_Utils._mod = function( a, b ) { "use strict"; return a - ( b * Math.floor( a / b ) ); }; WEF_Utils.newWikibaseItemSnak = /** * @param {String} * property * @param {String} * entityType * @param {Number} * numericId */ function( property, entityType, numericId ) { return { snaktype: 'value', property: property, datatype: 'wikibase-item', datavalue: { value: { 'entity-type': entityType, 'numeric-id': numericId, }, type: 'wikibase-entityid', }, }; }; /** * Date.parse with progressive enhancement for ISO 8601 * <https://github.com/csnover/js-iso8601> © 2011 Colin Snover * <http://zetafleet.com> * * Released under MIT license. * * Some changes by Vlsergey to adapt to Wikidata format */ WEF_Utils.parseISO8601 = function( date ) { var numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ]; var timestamp, struct, minutesOffset = 0; // ES5 §15.9.4.2 states that the string should attempt to be parsed as a // Date Time String Format string before falling back to any // implementation-specific date parsing, so that’s what we do, even if // native implementations could be faster // 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm if ( ( struct = /^([+\-]\d{1,11})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec( date ) ) ) { // avoid NaN timestamps caused by “undefined” values being passed to // Date.UTC for ( var i = 0, k; ( k = numericKeys[i] ); ++i ) { struct[k] = +struct[k] || 0; } // allow undefined days and months struct[2] = ( +struct[2] || 1 ) - 1; struct[3] = +struct[3] || 1; if ( struct[8] !== 'Z' && struct[9] !== undefined ) { minutesOffset = struct[10] * 60 + struct[11]; if ( struct[9] === '+' ) { minutesOffset = 0 - minutesOffset; } } timestamp = Date.UTC( struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7] ); } else { timestamp = Date.parse( date ); } return timestamp; }; /** * Preprocess different aspects of WEF_definition * <ul> * <li>Analyzes definition.template string and updates definition with new * functions like url() and normalize()</li> * <li>Create standard url function for commonsMedia datatype</li> * <ul> * * @param definition * {WEF_Definition} */ WEF_Utils.processDefinition = function( definition ) { if ( typeof definition.template !== 'undefined' ) { var newNormFunctions = []; $.each( $.isArray( definition.template ) ? definition.template : [ definition.template ], function( index, template ) { if ( template.indexOf( '$1' ) === -1 ) { mw.log.warn( 'Template of definition «' + definition.code + '» missing «$1» in «' + template + '»' ); return; } var prefix = template.substr( 0, template.indexOf( '$1' ) ); var suffix = template.substr( template.indexOf( '$1' ) + '$1'.length ); var rPrefix = WEF_Utils.regexpEscape( prefix ); var rSuffix = WEF_Utils.regexpEscape( suffix ); var pattern; if ( /^http:/.test( rPrefix ) ) { rPrefix = rPrefix.replace( /^http:/, 'https?:' ); } if ( /^https:/.test( rPrefix ) ) { rPrefix = rPrefix.replace( /^https:/, 'https?:' ); } pattern = '^' + rPrefix + '('; if ( typeof definition.check !== 'undefined' ) { var inner = WEF_Utils.regexpGetSource( definition.check ); inner = inner.replace( /^\^(.*)$/, '$1' ).replace( /^(.*)\$$/, '$1' ); pattern += inner; } else { pattern += '.*'; } pattern += ')'; if ( WEF_Utils.isEmpty( rSuffix ) ) { pattern += '$'; } else { pattern += rSuffix + '.*$'; } var regExp = new RegExp( pattern ); newNormFunctions.push( function( id ) { return id.replace( regExp, '$1' ); } ); } ); $.each( newNormFunctions, function( i, func ) { var old = definition.normalize; if ( typeof old !== 'undefined' ) { definition.normalize = function( id ) { return func( old( id ) ); }; } else { definition.normalize = function( id ) { return func( id ); }; } } ); if ( typeof definition.url === 'undefined' ) { var first = $.isArray( definition.template ) ? definition.template[0] : definition.template; definition.url = function( id ) { return first.replace( '$1', id ); }; } } if ( definition.datatype === 'commonsMedia' && typeof definition.url === 'undefined' ) { definition.url = WEF_Utils.urlCommons; } }, WEF_Utils.purge = function() { window.location .replace( mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/index.php?action=purge&title=' + encodeURIComponent( mw.config.get( 'wgPageName' ) ) ); }; WEF_Utils.purgeAsync = function() { $.ajax( { url: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php?action=purge&titles=' + encodeURIComponent( mw.config.get( 'wgPageName' ) ), } ); }; WEF_Utils.queryCentralAuthToken = function() { var d = $.Deferred(); $.ajax( { type: 'GET', url: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php' + '?format=json&action=tokens&type=centralauth', error: function( jqXHR, textStatus, errorThrown ) { d.reject( textStatus ); }, success: function( result ) { if ( result.error ) { d.reject( result.error.info ); return; } if ( !result.tokens || !result.tokens.centralauthtoken ) { d.reject( 'no centralauthtoken in response' ); return; } d.resolve( result.tokens.centralauthtoken ); }, } ); return d.promise(); }; WEF_Utils.queryWikidataToken = function( centralAuthToken, tokenType ) { if ( !WEF_Utils.isWikidata() && WEF_Utils.isEmpty( centralAuthToken ) ) { throw new Error( "Need to specify centralauthtoken for out-of-wikidata queries" ); } if ( WEF_Utils.isEmpty( tokenType ) ) { tokenType = 'csrf'; } var d = $.Deferred(); var prefix; if ( !WEF_Utils.isWikidata() ) { prefix = '//www.wikidata.org/w/api.php' // + '?origin=' + encodeURIComponent( location.protocol + mw.config.get( 'wgServer' ) ) // + '&centralauthtoken=' + encodeURIComponent( centralAuthToken ) // + '&format=json'; // } else { prefix = mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php' // + '?format=json'; } $.ajax( { type: 'GET', url: prefix // + '&action=query' // + '&meta=tokens' // + '&type=' + encodeURIComponent( tokenType ), error: function( jqXHR, textStatus, errorThrown ) { d.reject( textStatus ); }, success: function( result ) { if ( result.error ) { d.reject( result.error.info ); return; } var token = WEF_Utils.getFirstObjectValue( result.query.tokens ); if ( typeof token === 'undefined' ) { d.reject( 'no token in response' ); return; } d.resolve( token ); }, } ); return d.promise(); }; /** * @param s * {string} string to escapse * @returns {string} safe-to-use regexp pattern string */ WEF_Utils.regexpEscape = function( s ) { return s.replace( /[-\/\\^$*+?.()|[\]{}]/g, '\\$&' ); }; WEF_Utils.regexpGetHtmlPattern = function( regexp ) { var source = WEF_Utils.regexpGetSource( options.check ); if ( source.substr( 0, 1 ) !== '^' ) { source = '.*' + source; } if ( source.substr( source.lenght - 1, 1 ) !== '$' ) { source = source + '.*'; } return source; }; WEF_Utils.regexpGetSource = function( regexp ) { return regexp.toString().replace( /^\/(.*)\/[a-z]*$/, '$1' ); }; WEF_Utils.toRoman = ( function() { "use strict"; var limit = 3999; var v = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ]; var r = [ 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I' ]; return function( src ) { var n = Math.floor( src ); var val = 0; var s = ''; var i = 0; if ( n < 1 || n > limit ) return ''; while ( i < 13 ) { val = v[i]; while ( n >= val ) { n -= val; s += r[i]; } if ( n === 0 ) return s; ++i; } return ''; }; } )(); WEF_Utils.update = function( updates ) { if ( !( updates instanceof WEF_Updates ) ) { throw new Error( 'WEF_Updates object is expected' ); } var d = $.Deferred(); var i18n = wef_Editors_i18n; var dialog = $( document.createElement( 'div' ) ); dialog.attr( 'title', i18n.dialogSaveChangesTitle ); var progressUl = $( document.createElement( 'ul' ) ).appendTo( dialog ); var executionContext = { centralAuthToken: null, editToken: null, updates: updates, isWikidata: WEF_Utils.isWikidata(), localUrlPrefix: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php' + '?format=json', wikidataUrlPrefix: WEF_Utils.getWikidataApiPrefix(), getPrefixWithCentralAuthToken: function() { if ( this.isWikidata === true ) { return this.localUrlPrefix; } else { return this.wikidataUrlPrefix + '&centralauthtoken=' + encodeURIComponent( this.centralAuthToken ); } } }; var actions = []; var actionFinal = function() { dialog.dialog( 'close' ); d.resolve( executionContext.updates.entityId ); }; function createObtainCentralAuthTokenAction( onSuccessActionIndex, onFailureActionIndex ) { var progressItem = new WEF_ProgressItem( progressUl, i18n.actionObtainCentralAuthToken ); return function() { var onFailureAction = typeof onFailureActionIndex === 'undefined' ? actionFinal : actions[onFailureActionIndex]; var onSuccessAction = actions[onSuccessActionIndex]; progressItem.inProgress(); var d = WEF_Utils.queryCentralAuthToken(); d.done( function( centralauthtoken ) { executionContext.centralAuthToken = centralauthtoken; progressItem.success(); onSuccessAction(); } ); d.fail( function( textStatus ) { alert( i18n.errorObtainCentralAuthToken + ': ' + textStatus ); progressItem.failure( textStatus ); onFailureAction(); } ); return d; }; } var currentAction = 0; if ( !WEF_Utils.isWikidata() ) { actions[currentAction] = createObtainCentralAuthTokenAction( currentAction + 1 ); currentAction++; } /* * Edit token obtains once for all edit actions on the same element so far */ ( function() { var nextAction = currentAction + 1; var progressItem = new WEF_ProgressItem( progressUl, i18n.actionObtainEditToken ); actions[currentAction] = function() { var onFailureAction = actionFinal; var onSuccessAction = actions[nextAction]; progressItem.inProgress(); var d = WEF_Utils.queryWikidataToken( executionContext.centralAuthToken, 'csrf' ); d.done( function( editToken ) { executionContext.editToken = editToken; progressItem.success(); onSuccessAction(); } ); d.fail( function( textStatus ) { progressItem.failure( textStatus ); alert( i18n.errorObtainEditToken + ': ' + textStatus ); onFailureAction(); } ); }; currentAction++; } )(); /* Saving changes in entity, if required */ if ( !$.isEmptyObject( updates.data ) ) { /* * Each action (including obtaining edit token) need separate auth * token, because it's expiring in 10 seconds */ if ( WEF_Utils.isWikidata() === false ) { actions[currentAction] = createObtainCentralAuthTokenAction( currentAction + 1, currentAction + 2 ); currentAction++; } ( function() { var nextAction = currentAction + 1; var progressItem = new WEF_ProgressItem( progressUl, i18n.actionUpdateEntity ); actions[currentAction] = function() { var onFailureAction = actions[nextAction]; var onSuccessAction = actions[nextAction]; progressItem.inProgress(); $.ajax( { type: 'POST', url: executionContext.getPrefixWithCentralAuthToken() // + '&action=wbeditentity' // + ( WEF_Utils.isEmpty( executionContext.updates.entityId ) ? '&new=item' : '&id=' + executionContext.updates.entityId ) // + '&summary=' + encodeURIComponent( i18n.summary ) // , data: { data: JSON.stringify( updates.data ), token: executionContext.editToken, }, error: function( jqXHR, textStatus, errorThrown ) { progressItem.failure( textStatus ); alert( i18n.errorUpdateEntity + ': ' + textStatus ); onFailureAction(); return; }, success: function( result ) { if ( result.error ) { progressItem.failure( result.error.info ); alert( i18n.errorUpdateEntity + ': ' + result.error.info ); onFailureAction(); return; } if ( result.entity ) { executionContext.updates.entityId = result.entity.id; } progressItem.success(); onSuccessAction(); }, } ); }; currentAction++; } )(); } /* Remove claims in separate request */ if ( updates.removedClaims.length !== 0 ) { /* * Each action (including obtaining edit token) need separate auth * token, because it's expiring in 10 seconds */ if ( !WEF_Utils.isWikidata() ) { actions[currentAction] = createObtainCentralAuthTokenAction( currentAction + 1, currentAction + 2 ); currentAction++; } ( function() { var nextAction = currentAction + 1; var progressItem = new WEF_ProgressItem( progressUl, i18n.actionRemoveClaims ); actions[currentAction] = function() { var onFailureAction = actions[nextAction]; var onSuccessAction = actions[nextAction]; progressItem.inProgress(); $.ajax( { type: 'POST', url: executionContext.getPrefixWithCentralAuthToken() // + '&action=wbremoveclaims' // + '&summary=' + encodeURIComponent( i18n.summary ) // , data: { claim: updates.removedClaims.join( '|' ), token: executionContext.editToken, }, error: function( jqXHR, textStatus, errorThrown ) { progressItem.failure( textStatus ); alert( i18n.errorRemoveClaims + ': ' + textStatus ); onFailureAction(); return; }, success: function( result ) { if ( result.error ) { progressItem.failure( result.error.info ); alert( i18n.errorRemoveClaims + ': ' + result.error.info ); onFailureAction(); return; } progressItem.success(); onSuccessAction(); }, } ); }; currentAction++; } )(); } actions[currentAction] = actionFinal; dialog.dialog( { height: 'auto', width: 'auto', } ); actions[0](); return d.promise(); }; WEF_Utils.urlCommons = function( value ) { return WEF_Utils.urlNice( '//commons.wikimedia.org/wiki/File:' + escape( value ) ); }; /** * @type {function} * @returns {string} */ WEF_Utils.urlNice = ( function() { var abc = 'ёйцукенгшщзхъфывапролджэячсмитьбюáñú,'; abc = abc + abc.toUpperCase(); var patterns = []; var map = {}; for ( var i = 0; i < abc.length; i++ ) { var c = abc.charAt( i ); var e = encodeURIComponent( c ); patterns.push( e ); map[e] = c; } var pattern = new RegExp( patterns.join( '|' ), 'g' ); return function( stored ) { return stored.replace( pattern, function( match ) { return map[match]; } ); }; } )(); /** * @type {function} * @returns {string} */ WEF_Utils.urlUnnice = ( function() { var abc = 'ёйцукенгшщзхъфывапролджэячсмитьбюáñú,'; abc = abc + abc.toUpperCase(); var patterns = []; var map = {}; for ( var i = 0; i < abc.length; i++ ) { var c = abc.charAt( i ); var e = encodeURIComponent( c ); patterns.push( c ); map[c] = e; } var pattern = new RegExp( patterns.join( '|' ), 'g' ); return function( displayed ) { return displayed.replace( pattern, function( match ) { return map[match]; } ); }; } )(); WEF_Utils.wbGetEntities = function( params ) { "use strict"; var d = $.Deferred(); $.ajax( { type: 'POST', url: WEF_Utils.getWikidataApiPrefix() + '&action=wbgetentities&uselang=' + encodeURIComponent( WEF_Utils.getDefaultLanguageCode() ), data: params, error: function( jqXHR, textStatus, errorThrown ) { // too bad :-( console.log( "Unable to call 'wbgetentities'" ); console.log( textStatus ); console.log( errorThrown ); d.rejectWith( jqXHR, textStatus, errorThrown ); return; }, success: function( response ) { if ( response.error ) { console.log( "Unable to call 'wbgetentities': " + response.error.info ); d.rejectWith( null, response.error, null ); return; } d.resolve( response.entities ); }, } ); return d.promise(); }; window.wef_Editors_i18n = new WEF_Editors_i18n(); /** * Wikidata labels and description cache using local user storage (i.e. * client-side). Part of WE-Framework. * * @see https://github.com/vlsergey/WE-Framework * @author vlsergey */ WEF_LabelsCache = function() { /** * @const * @private */ var MAX_ITEMS_PER_REQUEST = 50; /** * @const * @private */ var LOCALSTORAGE_PREFIX_LABELS = 'wef-d-label-'; var LOCALSTORAGE_PREFIX_DESCRIPTIONS = 'wef-d-description-'; /** @private */ var cacheLabels = {}; /** @private */ var cacheDescriptions = {}; /** @private */ var queue = []; this.clear = function() { cacheLabels = {}; cacheDescriptions = {}; $.each( localStorage, function( key, value ) { if ( key.substr( 0, LOCALSTORAGE_PREFIX_LABELS.length ) === LOCALSTORAGE_PREFIX_LABELS ) { localStorage.removeItem( key ); } if ( key.substr( 0, LOCALSTORAGE_PREFIX_DESCRIPTIONS.length ) === LOCALSTORAGE_PREFIX_DESCRIPTIONS ) { localStorage.removeItem( key ); } } ); onUpdate(); }; this.clearCacheAndRequeue = function() { $.each( cacheLabels, function( key, item ) { localStorage.removeItem( LOCALSTORAGE_PREFIX_LABELS + key ); delete cacheLabels[key]; if ( queue.indexOf( key ) === -1 ) { queue.push( key ); } } ); $.each( cacheDescriptions, function( key, item ) { localStorage.removeItem( LOCALSTORAGE_PREFIX_DESCRIPTIONS + key ); delete cacheDescriptions[key]; if ( queue.indexOf( key ) === -1 ) { queue.push( key ); } } ); }; /** * Return cached value * * @param key * {string} * @param returnKeyIfEmpty * {boolean} * @returns {string} */ this.getLabel = function( key, returnKeyIfEmpty ) { WEF_Utils.assertCorrectEntityId( key ); var cached = cacheLabels[key]; if ( typeof cached !== 'undefined' ) { return cached; } var localCached = localStorage[LOCALSTORAGE_PREFIX_LABELS + key]; if ( isValid( localCached ) ) { cacheLabels[key] = localCached; return localCached; } if ( returnKeyIfEmpty !== false ) return key; }; /** * Return cached value * * @param key * {string} * @param returnKeyIfEmpty * {boolean} * @returns {string} */ this.getDescription = function( key, returnKeyIfEmpty ) { WEF_Utils.assertCorrectEntityId( key ); var cached = cacheDescriptions[key]; if ( typeof cached !== 'undefined' ) { return cached; } var localCached = localStorage[LOCALSTORAGE_PREFIX_DESCRIPTIONS + key]; if ( isValid( localCached ) ) { cacheDescriptions[key] = localCached; return localCached; } if ( returnKeyIfEmpty !== false ) return key; }; /** @private */ var isValid = function( value ) { return typeof value !== 'undefined' && value !== null; }; /** * Return cached value or queue values to be received from Wikidata * * @param key * {string} * @param listener * {function(string,string)} callback to be called (may be * several times) after cache or Wikidata retrieve * @return {string} immediatly available value */ this.getOrQueue = function( key, listener ) { WEF_Utils.assertCorrectEntityId( key ); if ( typeof listener !== 'function' ) { throw new Error( 'Listener not specified or not a function' ); } var getLabel = this.getLabel; var getDescription = this.getDescription; var cachedLabel = getLabel( key ); var cachedDescription = getDescription( key ); // call listener even if got from cache listener( cachedLabel, cachedDescription ); // label can be updated later, or user can change language $( this ).on( 'change', function() { var label = getLabel( key ); var description = getDescription( key ); listener( label, description ); } ); if ( !isValid( cachedLabel ) || cachedLabel === key || !isValid( cachedDescription ) || cachedDescription === key ) { queue.push( key ); return key; } return cachedLabel; }; var _this = this; /** * Notify listeners * * @private */ var onUpdate = function() { $( _this ).change(); }; /** * Add key to the queue if his label is missing from cache * * @param key * {string} */ this.queueForLabel = function( key ) { if ( !isValid( cacheLabels[key] ) ) { queue.push( key ); } }; /** * Add key to the queue if his description is missing from cache * * @param key * {string} */ this.queueForDescription = function( key ) { if ( !isValid( cacheDescriptions[key] ) ) { queue.push( key ); } }; /** Receive values from Wikidata, if any queued */ this.receiveLabels = function() { if ( queue.length === 0 ) { return; } var languages = [ mw.config.get( 'wgUserLanguage' ), mw.config.get( 'wgContentLanguage' ), 'en', 'ru', 'de' ]; var languagesString = encodeURIComponent( mw.config.get( 'wgUserLanguage' ) + '|' + mw.config.get( 'wgContentLanguage' ) + '|en|ru|de' ); // remove already known queue = jQuery.grep( queue, function( key ) { return !isValid( cacheLabels[key] ) || !isValid( cacheDescriptions[key] ); } ); var gotFromCache = []; var idsToQuery = []; $.each( queue, function( index, key ) { var cachedLabel = localStorage[LOCALSTORAGE_PREFIX_LABELS + key]; var cachedDescription = localStorage[LOCALSTORAGE_PREFIX_DESCRIPTIONS + key]; if ( isValid( cachedLabel ) ) { cacheLabels[key] = cachedLabel; gotFromCache.push( key ); } if ( isValid( cachedDescription ) ) { cacheDescriptions[key] = cachedDescription; gotFromCache.push( key ); } if ( !isValid( cachedLabel ) || isValid( cachedDescription ) ) { idsToQuery.push( key ); } } ); function onError( jqXHR, textStatus, errorThrown ) { mw.log.warn( 'Unable to load labels and descriptions from Wikidata: ' + textStatus ); } function onSuccess( result ) { if ( typeof result.error !== 'undefined' ) { mw.log.warn( result.error ); return; } $.each( result.entities, function( entityIndex, entity ) { var entityId = entity.id; if ( typeof entity.labels !== 'undefined' ) { for ( var l = 0; l < languages.length; l++ ) { var label = entity.labels[languages[l]]; if ( typeof label !== 'undefined' && !WEF_Utils.isEmpty( label.value ) ) { var title = label.value; cacheLabels[entityId] = title; if ( entityId.substring( 0, 1 ) === 'P' ) { localStorage[LOCALSTORAGE_PREFIX_LABELS + entityId] = title; } break; } } } if ( WEF_Utils.isEmpty( cacheLabels[entityId] ) ) { cacheLabels[entityId] = ''; } if ( typeof entity.descriptions !== 'undefined' ) { for ( var l = 0; l < languages.length; l++ ) { var description = entity.descriptions[languages[l]]; if ( typeof description !== 'undefined' && !WEF_Utils.isEmpty( description.value ) ) { var title = description.value; cacheDescriptions[entityId] = title; if ( entityId.substring( 0, 1 ) === 'P' ) { localStorage[LOCALSTORAGE_PREFIX_DESCRIPTIONS + entityId] = title; } break; } } } if ( WEF_Utils.isEmpty( cacheDescriptions[entityId] ) ) { cacheDescriptions[entityId] = ''; } } ); onUpdate(); } var total = idsToQuery.length; for ( var i = 0; i < total; i += MAX_ITEMS_PER_REQUEST ) { var idsString = ''; for ( var k = i; k < i + MAX_ITEMS_PER_REQUEST && k < total; k++ ) { if ( k != i ) { idsString = idsString + '|'; } idsString = idsString + idsToQuery[k]; } $.ajax( { url: WEF_Utils.getWikidataApiPrefix() // + '&action=wbgetentities' // + '&props=' + encodeURIComponent( 'labels|descriptions|aliases' ) // + '&languages=' + languagesString // + '&ids=' + encodeURIComponent( idsString ), dataType: 'json', error: onError, success: onSuccess, } ); } queue = jQuery.grep( queue, function( value ) { return idsToQuery.indexOf( value ) === -1; } ); if ( gotFromCache.length > 0 ) { onUpdate(); } }; // wef_i18n_label / wef_i18n_description support $( this ).on( 'change', function() { $( ".wef_i18n_label" ).each( function( index, item ) { var jqItem = $( item ); var entityId = jqItem.data( 'wef_i18n_entityId' ); if ( !WEF_Utils.isEmpty( entityId ) ) { var newLabel = wef_LabelsCache.getLabel( entityId, false ); if ( !WEF_Utils.isEmpty( newLabel ) ) { jqItem.text( newLabel ); } } } ); $( ".wef_i18n_description" ).each( function( index, item ) { var jqItem = $( item ); var entityId = jqItem.data( 'wef_i18n_entityId' ); if ( !WEF_Utils.isEmpty( entityId ) ) { var newDescription = wef_LabelsCache.getDescription( entityId, false ); if ( !WEF_Utils.isEmpty( newDescription ) ) { jqItem.text( newDescription ); } } } ); } ); }; WEF_LabelsCache.prototype.localizeDescription = function( jqElement, entityId ) { WEF_Utils.assertCorrectEntityId( entityId ); jqElement.addClass( 'wef_i18n_description' ); jqElement.data( 'wef_i18n_entityId', entityId ); this.queueForDescription( entityId ); var newDescription = this.getDescription( entityId, WEF_Utils.isEmpty( jqElement.text() ) ); if ( !WEF_Utils.isEmpty( newDescription ) ) jqElement.text( newDescription ); }; WEF_LabelsCache.prototype.localizeLabel = function( jqElement, entityId ) { WEF_Utils.assertCorrectEntityId( entityId ); jqElement.addClass( 'wef_i18n_label' ); jqElement.data( 'wef_i18n_entityId', entityId ); this.queueForLabel( entityId ); var newLabel = this.getLabel( entityId, WEF_Utils.isEmpty( jqElement.text() ) ); if ( !WEF_Utils.isEmpty( newLabel ) ) jqElement.text( newLabel ); }; var wef_LabelsCache = window.wef_LabelsCache = new WEF_LabelsCache(); /** * Caches types of properties. Required because sometimes entity contains the * property code and "novalue" mark, but not datatype marker. * * @see https://github.com/vlsergey/WE-Framework * @author vlsergey */ WEF_TypesCache = function() { /** * @const * @private */ var LOCALSTORAGE_PREFIX = 'wef-d-type-'; /** @private */ var cacheTypes = {}; /** * @param propertyId * {string} property ID to query * @param onSuccess * {function} callback handler for success * @param onFailure { */ this.getPropertyType = function( propertyId, onSuccess, onFailure ) { if ( !/^[P]\d+$/.test( propertyId ) ) { throw new Error( 'Incorrect property ID: ' + propertyId ); } var cached = cacheTypes[propertyId]; if ( typeof cached !== 'undefined' ) { onSuccess( cached ); return; } var localCached = localStorage[LOCALSTORAGE_PREFIX + propertyId]; if ( typeof localCached !== 'undefined' && localCached !== null ) { cacheTypes[propertyId] = localCached; onSuccess( localCached ); return; } // still no luck. Display modal window and ask Wikidata // TODO: i18n var dialog = $( document.createElement( 'div' ) ).attr( 'title', 'Get Wikidata property type' ).addClass( 'wef_dialog_no_close' ); var ul = $( document.createElement( 'ul' ) ).appendTo( dialog ); var progress = new WEF_ProgressItem( ul, 'Request property type from Wikidata' ); dialog.dialog( { width: 'auto', height: 'auto', resizable: false, modal: true, } ); /* We need new handlers to close dialog */ var onFailureNew = function( reason ) { progress.failure( reason ); dialog.dialog( 'close' ); onFailure( reason ); }; var onSuccessNew = function( datatype ) { progress.success(); dialog.dialog( 'close' ); onSuccess( datatype ); }; progress.inProgress(); $.ajax( { url: WEF_Utils.getWikidataApiPrefix() // + '&action=wbgetentities' // + '&props=' + encodeURIComponent( 'datatype' ) // + '&ids=' + encodeURIComponent( propertyId ), dataType: 'json', error: function( jqXHR, textStatus, errorThrown ) { onFailure( textStatus ); }, success: function( result ) { if ( typeof result.error !== 'undefined' ) { mw.log.warn( result.error ); onFailureNew( result.error ); return; } $.each( result.entities, function( entityIndex, entity ) { var dataType = entity.datatype; if ( typeof dataType !== 'undefined' && dataType !== null ) { localStorage[LOCALSTORAGE_PREFIX + entity.id] = dataType; cacheTypes[entity.id] = dataType; return; } } ); if ( typeof cacheTypes[propertyId] !== 'undefined' ) { onSuccessNew( cacheTypes[propertyId] ); } else { onFailureNew( 'no results returned for ' + propertyId ); } return; }, } ); return; }; this.putInCache = function( propertyId, dataType ) { if ( !/^[P]\d+$/.test( propertyId ) ) { throw new Error( 'Incorrect property ID: ' + propertyId ); } if ( !WEF_Utils.isEmpty( dataType ) ) { cacheTypes[propertyId] = dataType; localStorage[LOCALSTORAGE_PREFIX + propertyId] = dataType; } }; }; window.wef_TypesCache = new WEF_TypesCache(); /** * @param dataValue * {WEF_Snak} datavalue to initialize editor. If empty, new editor * will be created * @class */ WEF_SnakValueEditor = function( parent, dataDataType, editorDataType, initialDataValue, options ) { if ( typeof dataDataType === 'undefined' ) { throw new Error( 'DataType is not specified' ); } var i18n = wef_Editors_i18n; var snakValueEditor = this; var _jThis = $( this ); function changeF() { _jThis.trigger( 'change' ); } /** @type {string} */ var WIKIDATA_URI_PREFIX = 'http://www.wikidata.org/entity/'; /** @type {string} */ var GLOBE_EARTH = 'Q2'; /** @type {string[]} */ var GLOBES = [ // 'Q308', // MERCURY 'Q313', // VENUS GLOBE_EARTH, // EARTH 'Q405',// MOON 'Q111',// MARS 'Q319',// JUPITER ]; /** @type {string} */ var CALENDAR_GREGORIAN = 'Q1985727'; /** @type {string} */ var CALENDAR_JULIAN = 'Q1985786'; /** @type {string[]} */ var CALENDAR_MODELS = [ WIKIDATA_URI_PREFIX + CALENDAR_GREGORIAN, WIKIDATA_URI_PREFIX + CALENDAR_JULIAN ]; var PRECISION_DAYS = 11; var PRECISION_MONTHS = 10; var PRECISION_YEARS = 9; var PRECISION_CENTURIES = 7; this.mainElement = $( document.createElement( 'span' ) ).appendTo( parent ); var unsupportedF = function() { throw new Error( 'DataType "' + dataDataType + '" is not supported' ); }; this.hasValue = unsupportedF; this.getDataValue = unsupportedF; this.setDataValue = unsupportedF; this.getAsLabel = unsupportedF; var addTr = function( table, textLabel, textTitle, input ) { var tr = $( document.createElement( 'tr' ) ).attr( 'title', textTitle ).appendTo( table ); if ( typeof textLabel !== 'undefined' ) { input.uniqueId(); var th = $( document.createElement( 'th' ) ).appendTo( tr ); $( document.createElement( 'label' ) ).text( textLabel + ': ' ).attr( 'id', input.attr( 'id' ) ).appendTo( th ); } var td = $( document.createElement( 'td' ) ).appendTo( tr ); if ( typeof textLabel === 'undefined' ) { td.attr( 'colspan', 2 ); } td.append( input ); }; if ( typeof editorDataType === 'undefined' ) { // autodetect enabled editorDataType = dataDataType; if ( editorDataType === 'time' ) { if ( typeof initialDataValue === 'undefined' || typeof initialDataValue.value === 'undefined' || CALENDAR_MODELS.indexOf( initialDataValue.value.calendarmodel ) === -1 ) { editorDataType = 'time-days-gregorian'; } else { var initialValue = initialDataValue.value; if ( !/^[\\+\\-][0-9]{1,4}\-/.test( initialValue.time ) ) { editorDataType = 'time'; } else if ( !WEF_Utils.isEmpty( initialValue ) && !WEF_Utils.isEmpty( initialValue.precision ) ) { var precision = initialValue.precision; if ( precision === PRECISION_CENTURIES && initialValue.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) === CALENDAR_GREGORIAN ) { editorDataType = 'time-centuries'; } else if ( precision === PRECISION_YEARS && initialValue.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) === CALENDAR_GREGORIAN ) { editorDataType = 'time-years'; } else if ( precision === PRECISION_MONTHS && initialValue.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) === CALENDAR_GREGORIAN ) { editorDataType = 'time-months'; } else if ( precision === PRECISION_DAYS ) { if ( initialValue.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) === CALENDAR_GREGORIAN ) { editorDataType = 'time-days-gregorian'; } else { editorDataType = 'time-days'; } } } } } if ( editorDataType === 'quantity' ) { if ( typeof initialDataValue === 'undefined' || typeof initialDataValue.value === 'undefined' ) { editorDataType = 'quantity-exact'; } else { var unit = initialDataValue.value.unit; var amount = initialDataValue.value.amount; var upperBound = initialDataValue.value.upperBound; var lowerBound = initialDataValue.value.lowerBound; if ( unit === '1' && amount === upperBound && amount === lowerBound ) { editorDataType = 'quantity-exact'; } else if ( unit === '1' && ( Number( upperBound ) - Number( amount ) ) === ( Number( amount ) - Number( lowerBound ) ) ) { editorDataType = 'quantity-plus-minus'; } } } } this.dataDataType = dataDataType; this.editorDataType = editorDataType; this.mainElement.addClass( 'wef_snak_value_editor_' + editorDataType ); var switchDataType = function( newEditorDataType, dataValue ) { snakValueEditor.mainElement.remove(); WEF_SnakValueEditor.call( snakValueEditor, parent, snakValueEditor.dataDataType, newEditorDataType, dataValue, options ); }; var selectQuantityMode; if ( editorDataType.substring( 0, 'quantity-'.length ) === 'quantity-' ) { selectQuantityMode = $( document.createElement( 'select' ) ).addClass( 'wef_quantity_mode' ); selectQuantityMode.append( $( document.createElement( 'option' ) ).attr( 'value', 'quantity-exact' ).text( i18n.inputQuantityModeExact ) ); selectQuantityMode.append( $( document.createElement( 'option' ) ).attr( 'value', 'quantity-plus-minus' ).text( i18n.inputQuantityModePlusMinus ) ); selectQuantityMode.append( $( document.createElement( 'option' ) ).attr( 'value', 'quantity' ).text( i18n.inputQuantityModeOther ) ); selectQuantityMode.val( editorDataType ); selectQuantityMode.change( function() { var newDataType = selectQuantityMode.val(); if ( newDataType !== editorDataType ) { if ( snakValueEditor.hasValue() ) { switchDataType( newDataType, snakValueEditor.getDataValue() ); } else { switchDataType( newDataType, undefined ); } } } ); } var selectDateTimePrecision; if ( editorDataType.substring( 0, 5 ) === 'time-' ) { selectDateTimePrecision = $( document.createElement( 'select' ) ).addClass( 'wef_select_date_time_precision' ); selectDateTimePrecision.attr( 'title', i18n.inputTimePrecisionTitle ); selectDateTimePrecision.append( $( document.createElement( 'option' ) ) // .attr( 'value', 'time-days' ).data( 'precision', PRECISION_DAYS ).text( i18n['timePrecision' + PRECISION_DAYS] ) ); selectDateTimePrecision.append( $( document.createElement( 'option' ) ) // .attr( 'value', 'time-months' ).data( 'precision', PRECISION_MONTHS ).text( i18n['timePrecision' + PRECISION_MONTHS] ) ); selectDateTimePrecision.append( $( document.createElement( 'option' ) ) // .attr( 'value', 'time-years' ).data( 'precision', PRECISION_YEARS ).text( i18n['timePrecision' + PRECISION_YEARS] ) ); selectDateTimePrecision.append( $( document.createElement( 'option' ) ) // .attr( 'value', 'time-centuries' ).data( 'precision', PRECISION_CENTURIES ).text( i18n['timePrecision' + PRECISION_CENTURIES] ) ); selectDateTimePrecision.append( $( document.createElement( 'option' ) ).attr( 'value', 'time' ).text( i18n.timePrecisionOther ) ); if ( editorDataType === 'time-days-gregorian' ) { selectDateTimePrecision.val( 'time-days' ); } else { selectDateTimePrecision.val( editorDataType ); } selectDateTimePrecision.change( function() { var newDataType = selectDateTimePrecision.val(); if ( newDataType !== editorDataType ) { if ( snakValueEditor.hasValue() ) { var dataValue = snakValueEditor.getDataValue(); if ( typeof dataValue.value !== 'undefined' && newDataType !== 'time' ) { dataValue.value.precision = Number( selectDateTimePrecision.find( 'option:selected' ).data( 'precision' ) ); } switchDataType( newDataType, dataValue ); } else { switchDataType( newDataType, undefined ); } } } ); } if ( editorDataType === 'commonsMedia' ) { ( function() { var input = $( document.createElement( 'input' ) ).attr( 'type', 'text' ).addClass( 'wef_commonsMedia' ).appendTo( snakValueEditor.mainElement ); this.setDataValue = function( newDataValue ) { input.val( newDataValue.value ); }; this.hasValue = function() { return input.val() != null && !WEF_Utils.isEmpty( input.val().trim() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'string', value: input.val() == null ? null : input.val().trim(), }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'a' ) ).attr( 'href', '//commons.wikimedia.org/wiki/File:' + encodeURI( input.val() ) ).text( input.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'commonsMedia', this.getDataValue(), span ); return span; }; input.autocomplete( { source: function( request, response ) { var term = request.term; $.ajax( { type: 'GET', dataType: 'json', url: '//commons.wikimedia.org/w/api.php?format=json&origin=' + encodeURIComponent( location.protocol + mw.config.get( 'wgServer' ) ) + '&action=query&list=prefixsearch&psnamespace=6&pslimit=15&pssearch=' + encodeURIComponent( term ), } ).done( function( result ) { var list = []; $.each( result.query.prefixsearch, function( index, p ) { list.push( p.title.substring( 'File:'.length ) ); } ); response( list ); } ); }, select: function( event, ui ) { input.val( ui.item.value ); input.change(); }, } ); input.change( changeF ); input.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'globe-coordinate' ) { ( function() { var table = $( document.createElement( 'table' ) ).addClass( 'wef_globecoordinate_table' ).appendTo( this.mainElement ); var inputLatitude = $( document.createElement( 'input' ) ) // /**/.attr( 'type', 'number' ).attr( 'step', 'any' ) // /**/.attr( 'min', '-90' ).attr( 'max', '90' ).attr( 'pattern', '[0-9]{1,2}(\.[0-9]{0,9})?' ) // /**/.addClass( 'wef_globecoordinate_latitude' ) // /**/.attr( 'placeholder', i18n.inputGlobeLatitudeLabel ); var inputLongitude = $( document.createElement( 'input' ) ) // /**/.attr( 'type', 'number' ).attr( 'step', 'any' ) // /**/.attr( 'min', '-180' ).attr( 'max', '180' ).attr( 'pattern', '[0-9]{1,3}(\.[0-9]{0,9})?' ) // /**/.addClass( 'wef_globecoordinate_longitude' ) // /**/.attr( 'placeholder', i18n.inputGlobeLongitudeLabel ); var inputAltitude = $( document.createElement( 'input' ) ) // /**/.attr( 'type', 'number' ).attr( 'step', 'any' ) // /**/.addClass( 'wef_globecoordinate_altitude' ) // /**/.attr( 'placeholder', i18n.inputGlobeAltitudeLabel ); var inputPrecision = $( document.createElement( 'input' ) ) // /**/.attr( 'type', 'number' ) // /**/.attr( 'step', 'any' ) // /**/.addClass( 'wef_globecoordinate_precision' ) // /**/.attr( 'placeholder', i18n.inputGlobePrecisionLabel ); var inputGlobe = new WEF_ItemSelect(); inputGlobe.select.addClass( 'wef_globecoordinate_globe' ); $.each( GLOBES, function( index, item ) { inputGlobe.addOption( item ); } ); inputGlobe.val( GLOBE_EARTH ); addTr( table, i18n.inputGlobeLatitudeLabel, i18n.inputGlobeLatitudeTitle, inputLatitude ); addTr( table, i18n.inputGlobeLongitudeLabel, i18n.inputGlobeLongitudeTitle, inputLongitude ); addTr( table, i18n.inputGlobeAltitudeLabel, i18n.inputGlobeAltitudeTitle, inputAltitude ); addTr( table, i18n.inputGlobePrecisionLabel, i18n.inputGlobePrecisionTitle, inputPrecision ); addTr( table, i18n.inputGlobeGlobeLabel, i18n.inputGlobeGlobeTitle, inputGlobe.select ); this.setDataValue = function( newDataValue ) { inputLatitude.val( newDataValue.value.latitude == null ? '' : newDataValue.value.latitude ); inputLongitude.val( newDataValue.value.longitude == null ? '' : newDataValue.value.longitude ); inputAltitude.val( newDataValue.value.altitude == null ? '' : newDataValue.value.altitude ); inputPrecision.val( newDataValue.value.precision == null ? '' : newDataValue.value.precision ); inputGlobe.val( newDataValue.value.globe.substr( WIKIDATA_URI_PREFIX.length ) ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( inputLatitude.val() ) || !WEF_Utils.isEmpty( inputLongitude.val() ) || !WEF_Utils.isEmpty( inputAltitude.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'globecoordinate', value: { latitude: !WEF_Utils.isEmpty( inputLatitude.val() ) ? Number( inputLatitude.val() ) : null, longitude: !WEF_Utils.isEmpty( inputLongitude.val() ) ? Number( inputLongitude.val() ) : null, altitude: !WEF_Utils.isEmpty( inputAltitude.val() ) ? Number( inputAltitude.val() ) : null, precision: !WEF_Utils.isEmpty( inputPrecision.val() ) ? Number( inputPrecision.val() ) : 0, globe: WIKIDATA_URI_PREFIX + inputGlobe.val(), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_globe' ).text( inputLatitude.val() + "; " + inputLongitude.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'globe-coordinate', this.getDataValue(), span ); return span; }; inputLatitude.change( changeF ); inputLatitude.keyup( changeF ); inputLongitude.change( changeF ); inputLongitude.keyup( changeF ); inputAltitude.change( changeF ); inputAltitude.keyup( changeF ); inputPrecision.change( changeF ); inputPrecision.keyup( changeF ); inputGlobe.select.change( changeF ); inputGlobe.select.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'monolingualtext' ) { ( function() { var table = $( document.createElement( 'table' ) ).addClass( 'wef_monolingualtext_table' ).appendTo( snakValueEditor.mainElement ); var tr = $( document.createElement( 'tr' ) ).addClass( 'wef_monolingualtext_tr' ).appendTo( table ); var langSelect = new WEF_LanguageInput().appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_monolingualtext_td_language' ).appendTo( tr ) ); var input = $( document.createElement( 'input' ) ).attr( 'type', 'text' ).addClass( 'wef_monolingualtext_text' ).appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_monolingualtext_td_text' ).appendTo( tr ) ); try { if ( typeof options === 'object' && typeof options.check === 'object' ) { input.attr( 'pattern', WEF_Utils.regexpGetHtmlPattern( options.check ) ); } } catch ( err ) { mw.log.warn( 'Unable to attach check pattern to input: ' + err ); } this.setDataValue = function( newDataValue ) { langSelect.val( newDataValue.value.language ); input.val( newDataValue.value.text ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( input.val().trim() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'monolingualtext', value: { text: input.val() == null ? null : input.val().trim(), language: langSelect.val(), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).text( '(' + langSelect.val() + ') ' + input.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'monolingualtext', this.getDataValue(), span ); return span; }; langSelect.change( changeF ); langSelect.keyup( changeF ); input.change( changeF ); input.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'quantity' ) { ( function() { var table = $( document.createElement( 'table' ) ).addClass( 'wef_quantity_table' ).appendTo( this.mainElement ); var inputUnit = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_unit' ); var inputLowerBound = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_lower_bound' ); var inputAmount = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_amount' ); var inputUpperBound = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_upper_bound' ); addTr( table, i18n.inputQuantityUnitLabel, i18n.inputQuantityUnitTitle, inputUnit ); addTr( table, i18n.inputQuantityLowerBoundLabel, i18n.inputQuantityLowerBoundTitle, inputLowerBound ); addTr( table, i18n.inputQuantityAmountLabel, i18n.inputQuantityAmountTitle, inputAmount ); addTr( table, i18n.inputQuantityUpperBoundLabel, i18n.inputQuantityUpperBoundTitle, inputUpperBound ); this.setDataValue = function( newDataValue ) { inputUnit.val( newDataValue.value.unit ); inputLowerBound.val( newDataValue.value.lowerBound ); inputAmount.val( newDataValue.value.amount ); inputUpperBound.val( newDataValue.value.upperBound ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( inputAmount.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'quantity', value: { unit: inputUnit.val(), lowerBound: WEF_Utils.formatQuantity( inputLowerBound.val() ), amount: WEF_Utils.formatQuantity( inputAmount.val() ), upperBound: WEF_Utils.formatQuantity( inputUpperBound.val() ), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_quantity' ).text( lowerBound.val() + ' / ' + inputAmount.val() + ' / ' + inputUpperBound.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'quantity', this.getDataValue(), span ); return span; }; inputUnit.change( changeF ); inputUnit.keyup( changeF ); inputLowerBound.change( changeF ); inputLowerBound.keyup( changeF ); inputAmount.change( changeF ); inputAmount.keyup( changeF ); inputUpperBound.change( changeF ); inputUpperBound.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'quantity-exact' ) { ( function() { selectQuantityMode.appendTo( this.mainElement ); var inputAmount = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_amount' ).appendTo( this.mainElement ); this.setDataValue = function( newDataValue ) { inputAmount.val( newDataValue.value.amount ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( inputAmount.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'quantity', value: { unit: '1', lowerBound: WEF_Utils.formatQuantity( inputAmount.val() ), amount: WEF_Utils.formatQuantity( inputAmount.val() ), upperBound: WEF_Utils.formatQuantity( inputAmount.val() ), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_quantity' ).text( inputAmount.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'quantity', this.getDataValue(), span ); return span; }; inputAmount.change( changeF ); inputAmount.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'quantity-plus-minus' ) { ( function() { selectQuantityMode.appendTo( this.mainElement ); var inputAmount = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_amount' ).appendTo( this.mainElement ); var spanPlusMinus = $( document.createElement( 'span' ) ).text( '±' ).appendTo( this.mainElement ); var inputDifference = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).addClass( 'wef_quantity_difference' ).appendTo( this.mainElement ); this.setDataValue = function( newDataValue ) { inputDifference.val( Number( newDataValue.value.amount ) - Number( newDataValue.value.lowerBound ) ); inputAmount.val( newDataValue.value.amount ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( inputAmount.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } var amount = Number( inputAmount.val() ); var difference = Number( inputDifference.val() ); return { type: 'quantity', value: { unit: '1', lowerBound: WEF_Utils.formatQuantity( amount - difference ), amount: WEF_Utils.formatQuantity( inputAmount.val() ), upperBound: WEF_Utils.formatQuantity( amount + difference ), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_quantity' ).text( inputAmount.val() + '±' + inputDifference.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'quantity', this.getDataValue(), span ); return span; }; inputAmount.change( changeF ); inputAmount.keyup( changeF ); inputDifference.change( changeF ); inputDifference.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'string' ) { ( function() { var input = $( document.createElement( 'input' ) ).attr( 'type', 'text' ).addClass( 'wef_string' ).appendTo( this.mainElement ); if ( typeof options === 'object' && typeof options.autocomplete === 'object' ) { input.autocomplete( options.autocomplete ); input.on( 'autocompleteselect', function( event, ui ) { input.val( ui.item.value ); input.change(); } ); } try { if ( typeof options === 'object' && typeof options.check === 'object' ) { input.attr( 'pattern', WEF_Utils.regexpGetHtmlPattern( options.check ) ); } } catch ( err ) { mw.log.warn( 'Unable to attach check pattern to input: ' + err ); } this.setDataValue = function( newDataValue ) { input.val( newDataValue.value ); }; this.hasValue = function() { return input.val() != null && !WEF_Utils.isEmpty( input.val().trim() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'string', value: input.val() == null ? null : input.val().trim(), }; }; this.getAsLabel = function() { return $( document.createElement( 'span' ) ).text( input.val() ); }; input.change( changeF ); input.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'time' ) { ( function() { var table = $( document.createElement( 'table' ) ).addClass( 'wef_time_table' ).appendTo( this.mainElement ); var inputTime = $( document.createElement( 'input' ) ).attr( 'type', 'text' ).addClass( 'wef_time_time' ).attr( 'placeholder', i18n.inputTimeTimeTitle ); var inputTimeZone = $( document.createElement( 'input' ) ).attr( 'type', 'text' ).addClass( 'wef_time_timezone' ).attr( 'placeholder', i18n.inputTimeTimeZoneTitle ); var inputPrecision = $( document.createElement( 'select' ) ).addClass( 'wef_time_precision' ); for ( var i = 0; i < 15; i++ ) { var option = $( document.createElement( 'option' ) ); option.attr( 'value', i ); option.text( i18n['timePrecision' + i] ); inputPrecision.append( option ); } inputPrecision.val( 11 ); var inputCalendarModel = new WEF_ItemSelect(); inputCalendarModel.select.addClass( 'wef_time_calendarmodel' ); inputCalendarModel.addOption( CALENDAR_GREGORIAN ); inputCalendarModel.addOption( CALENDAR_JULIAN ); inputCalendarModel.val( CALENDAR_GREGORIAN ); addTr( table, i18n.inputTimeTimeLabel, i18n.inputTimeTimeTitle, inputTime ); addTr( table, i18n.inputTimeTimeZoneLabel, i18n.inputTimeTimeZoneTitle, inputTimeZone ); addTr( table, i18n.inputTimePrecisionLabel, i18n.inputTimePrecisionTitle, inputPrecision ); addTr( table, i18n.inputTimeCalendarModelLabel, i18n.inputTimeCalendarModelTitle, inputCalendarModel.select ); this.setDataValue = function( newDataValue ) { inputTime.val( newDataValue.value.time ); inputTimeZone.val( newDataValue.value.timezone ); inputPrecision.val( newDataValue.value.precision ); inputCalendarModel.val( newDataValue.value.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( inputTime.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'time', value: { time: inputTime.val(), timezone: Number( inputTimeZone.val() ), precision: Number( inputPrecision.val() ), before: 0, after: 0, calendarmodel: WIKIDATA_URI_PREFIX + inputCalendarModel.val(), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_time' ).text( inputTime.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'time', this.getDataValue(), span ); return span; }; inputTime.change( changeF ); inputTime.keyup( changeF ); inputTimeZone.change( changeF ); inputTimeZone.keyup( changeF ); inputPrecision.change( changeF ); inputPrecision.keyup( changeF ); inputCalendarModel.select.change( changeF ); inputCalendarModel.select.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'time-days' ) { ( function() { var grDays = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'min', '1' ).attr( 'step', '1' ).attr( 'max', '31' ).addClass( 'wef_time_day' ) .appendTo( this.mainElement ).val( '' ); var grMonths = $( document.createElement( 'select' ) ).addClass( 'wef_time_month' ).appendTo( this.mainElement ); WEF_Utils.fillSelectWithMonthes( grMonths ); var grYears = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'step', '1' ).val( '' ).addClass( 'wef_time_year' ).appendTo( this.mainElement ); var grSpan = $( document.createElement( 'span' ) ).append( grDays, grMonths, grYears ); var juDays = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'min', '1' ).attr( 'step', '1' ).attr( 'max', '31' ).addClass( 'wef_time_day' ) .appendTo( this.mainElement ).val( '' ); var juMonths = $( document.createElement( 'select' ) ).addClass( 'wef_time_month' ).appendTo( this.mainElement ); WEF_Utils.fillSelectWithMonthes( juMonths ); var juYears = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'step', '1' ).val( '' ).addClass( 'wef_time_year' ).appendTo( this.mainElement ); var juSpan = $( document.createElement( 'span' ) ).append( juDays, juMonths, juYears ); var inputCalendarModel = new WEF_ItemSelect(); inputCalendarModel.select.addClass( 'wef_time_calendarmodel' ); inputCalendarModel.addOption( CALENDAR_GREGORIAN ); inputCalendarModel.addOption( CALENDAR_JULIAN ); inputCalendarModel.val( CALENDAR_GREGORIAN ); var table = $( document.createElement( 'table' ) ).addClass( 'wef_time_table' ).appendTo( this.mainElement ); var addTrExt = function( textLabel, labelQId, textTitle, input ) { var tr = $( document.createElement( 'tr' ) ).attr( 'title', textTitle ).appendTo( table ); if ( typeof textLabel !== 'undefined' ) { input.uniqueId(); var th = $( document.createElement( 'th' ) ).appendTo( tr ); $( document.createElement( 'label' ) ).text( textLabel + ': ' ).attr( 'id', input.attr( 'id' ) ).appendTo( th ); } if ( typeof labelQId !== 'undefined' ) { input.uniqueId(); var th = $( document.createElement( 'th' ) ).appendTo( tr ); var jLabel = $( document.createElement( 'label' ) ).text( labelQId + ': ' ).attr( 'id', input.attr( 'id' ) ).appendTo( th ); wef_LabelsCache.getOrQueue( labelQId, function( label, title ) { jLabel.text( label + ': ' ); jLabel.attr( 'title', title ); } ); } var td = $( document.createElement( 'td' ) ).appendTo( tr ); if ( typeof textLabel === 'undefined' && typeof labelQId === 'undefined' ) { td.attr( 'colspan', 2 ); } td.append( input ); }; addTrExt( i18n.inputTimePrecisionLabel, undefined, i18n.inputTimePrecisionTitle, selectDateTimePrecision ); addTrExt( i18n.inputTimeCalendarModelLabel, undefined, i18n.inputTimeCalendarModelTitle, inputCalendarModel.select ); addTrExt( undefined, 'Q12138', i18n.inputTimeAsGregorianLabel, grSpan ); addTrExt( undefined, 'Q11184', i18n.inputTimeAsJulianLabel, juSpan ); table.appendTo( this.mainElement ); var inProgress = false; var recalculateGregorian = function() { if ( inProgress ) return; inProgress = true; if ( !ifSpecified( juDays, juMonths, juYears ) ) { grDays.val( '' ); grMonths.val( -1 ); grYears.val( '' ); } else { var converted = WEF_Utils.convertJulianToGregorian( juYears.val(), juMonths.val(), juDays.val() ); grDays.val( converted[2] ); grMonths.val( converted[1] ); grYears.val( converted[0] ); } inProgress = false; }; var recalculateJulian = function() { if ( inProgress ) return; inProgress = true; if ( !ifSpecified( grDays, grMonths, grYears ) ) { juDays.val( '' ); juMonths.val( -1 ); juYears.val( '' ); } else { var converted = WEF_Utils.convertGregorianToJulian( grYears.val(), grMonths.val(), grDays.val() ); juDays.val( converted[2] ); juMonths.val( converted[1] ); juYears.val( converted[0] ); } inProgress = false; }; var ifSpecified = function( days, months, years ) { return !WEF_Utils.isEmpty( days.val() ) && Number( days.val() ) !== 0 // && !WEF_Utils.isEmpty( months.val() ) && Number( months.val() ) !== -1 && Number( months.val() ) !== 0 // && !WEF_Utils.isEmpty( years.val() ) && Number( years.val() ) !== 0; }; this.setDataValue = function( newDataValue ) { if ( !/^[\\+\\-][0-9]{1,4}\-/.test( newDataValue.value.time ) ) { switchDataType( 'time', newDataValue ); return; } inputCalendarModel.val( newDataValue.value.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) ); var date = WEF_Utils.parseISO8601( newDataValue.value.time ); if ( isNaN( date ) ) { switchDataType( 'time', newDataValue ); return; } date = new Date( date ); grYears.val( date.getUTCFullYear() ); grMonths.val( date.getUTCMonth() + 1 ); grDays.val( date.getUTCDate() ); recalculateJulian(); }; this.hasValue = function() { "use strict"; return ifSpecified( grDays, grMonths, grYears ); }; this.getDataValue = function() { "use strict"; if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'time', value: { time: WEF_Utils.formatDate( grYears.val(), grMonths.val(), grDays.val() ), timezone: 0, precision: PRECISION_DAYS, before: 0, after: 0, calendarmodel: WIKIDATA_URI_PREFIX + inputCalendarModel.val(), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_time_days' ).text( juDays.val() + ' ' + mw.config.get( 'wgMonthNames' )[juMonths.val()] + ' ' + juYears.val() + ' ( ' + grDays.val() + ' ' + mw.config.get( 'wgMonthNames' )[grMonths.val()] + ' ' + grYears.val() ) + ' )'; if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'time', this.getDataValue(), span ); return span; }; grDays.change( changeF ); grDays.keyup( changeF ); grMonths.change( changeF ); grMonths.keyup( changeF ); grYears.change( changeF ); grYears.keyup( changeF ); inputCalendarModel.select.change( changeF ); inputCalendarModel.select.keyup( changeF ); grDays.change( recalculateJulian ); grDays.keyup( recalculateJulian ); grMonths.change( recalculateJulian ); grMonths.keyup( recalculateJulian ); grYears.change( recalculateJulian ); grYears.keyup( recalculateJulian ); juDays.change( recalculateGregorian ); juDays.keyup( recalculateGregorian ); juMonths.change( recalculateGregorian ); juMonths.keyup( recalculateGregorian ); juYears.change( recalculateGregorian ); juYears.keyup( recalculateGregorian ); } ).call( this ); } else if ( editorDataType === 'time-days-gregorian' ) { ( function() { selectDateTimePrecision.appendTo( this.mainElement ); var days = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'min', '1' ).attr( 'step', '1' ).attr( 'max', '31' ).val( '' ).addClass( 'wef_time_day' ).appendTo( this.mainElement ); var months = $( document.createElement( 'select' ) ).addClass( 'wef_time_month' ).appendTo( this.mainElement ); WEF_Utils.fillSelectWithMonthes( months ); var years = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'step', '1' ).val( '' ).addClass( 'wef_time_year' ).appendTo( this.mainElement ); var showJulianSpan = $( document.createElement( 'span' ) ).addClass( 'wef_time_oldstyle_span' ).appendTo( this.mainElement ); var showJulianCheckbox = $( document.createElement( 'input' ) ).attr( 'type', 'checkbox' ).addClass( 'wef_time_oldstyle' ); showJulianCheckbox.attr( 'title', i18n.checkboxShowJulianTitle ); showJulianCheckbox.uniqueId(); showJulianCheckbox.change( changeF ); showJulianCheckbox.keyup( changeF ); showJulianCheckbox.appendTo( showJulianSpan ); var afterCalendarModelChange = function() { if ( showJulianCheckbox.is( ':checked' ) ) { if ( snakValueEditor.hasValue() ) { switchDataType( 'time-days', snakValueEditor.getDataValue() ); } else { switchDataType( 'time-days', undefined ); } wef_LabelsCache.receiveLabels(); } }; showJulianCheckbox.change( afterCalendarModelChange ); showJulianCheckbox.keyup( afterCalendarModelChange ); var showJulianCheckboxLabel = $( document.createElement( 'label' ) ); showJulianCheckboxLabel.attr( 'for', showJulianCheckbox.attr( 'id' ) ); showJulianCheckboxLabel.attr( 'title', i18n.checkboxShowJulianTitle ); showJulianCheckboxLabel.text( i18n.checkboxShowJulian ); showJulianCheckboxLabel.appendTo( showJulianSpan ); this.setDataValue = function( newDataValue ) { if ( !/^[\\+\\-][0-9]{1,4}\-/.test( newDataValue.value.time ) ) { switchDataType( 'time', newDataValue ); return; } if ( newDataValue.value.calendarmodel.substr( WIKIDATA_URI_PREFIX.length ) !== CALENDAR_GREGORIAN ) { switchDataType( 'time-days', newDataValue ); return; } var date = WEF_Utils.parseISO8601( newDataValue.value.time ); if ( isNaN( date ) ) { switchDataType( 'time', newDataValue ); return; } date = new Date( date ); years.val( date.getUTCFullYear() ); months.val( date.getUTCMonth() + 1 ); days.val( date.getUTCDate() ); showJulianCheckbox.attr( 'checked', false ); }; this.hasValue = function() { "use strict"; return !WEF_Utils.isEmpty( days.val() ) && Number( days.val() ) !== 0 // && !WEF_Utils.isEmpty( months.val() ) && Number( months.val() ) !== -1 && Number( months.val() ) !== 0 // && !WEF_Utils.isEmpty( years.val() ) && Number( years.val() ) !== 0; }; this.getDataValue = function() { "use strict"; if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'time', value: { time: WEF_Utils.formatDate( years.val(), months.val(), days.val() ), timezone: 0, precision: PRECISION_DAYS, before: 0, after: 0, calendarmodel: WIKIDATA_URI_PREFIX + ( showJulianCheckbox.is( ':checked' ) ? CALENDAR_JULIAN : CALENDAR_GREGORIAN ), }, }; }; this.getAsLabel = function() { "use strict"; var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_time_days' ).text( days.val() + ' ' + mw.config.get( 'wgMonthNames' )[months.val()] + ' ' + years.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'time', this.getDataValue(), span ); return span; }; days.change( changeF ); days.keyup( changeF ); months.change( changeF ); months.keyup( changeF ); years.change( changeF ); years.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'time-months' ) { ( function() { selectDateTimePrecision.appendTo( this.mainElement ); var months = $( document.createElement( 'select' ) ).addClass( 'wef_time_month' ).appendTo( this.mainElement ); WEF_Utils.fillSelectWithMonthes( months ); var years = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'step', '1' ).appendTo( this.mainElement ); this.setDataValue = function( newDataValue ) { if ( !/^[\\+\\-][0-9]{1,4}\-/.test( newDataValue.value.time ) ) { switchDataType( 'time', newDataValue ); return; } var date = WEF_Utils.parseISO8601( newDataValue.value.time ); if ( isNaN( date ) ) { switchDataType( 'time', newDataValue ); return; } date = new Date( date ); months.val( date.getMonth() + 1 ); years.val( date.getFullYear() ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( months.val() ) || !WEF_Utils.isEmpty( years.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'time', value: { time: WEF_Utils.formatDate( years.val(), months.val() ), timezone: 0, precision: PRECISION_MONTHS, before: 0, after: 0, calendarmodel: WIKIDATA_URI_PREFIX + CALENDAR_GREGORIAN, }, }; }; this.getAsLabel = function() { var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_time_months' ).text( mw.config.get( 'wgMonthNames' )[months.val()] + ' ' + years.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'time', this.getDataValue(), span ); return span; }; months.change( changeF ); months.keyup( changeF ); years.change( changeF ); years.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'time-years' ) { ( function() { selectDateTimePrecision.appendTo( this.mainElement ); var years = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'step', '1' ).appendTo( this.mainElement ); this.setDataValue = function( newDataValue ) { if ( !/^[\\+\\-][0-9]{1,4}\-/.test( newDataValue.value.time ) ) { switchDataType( 'time', newDataValue ); return; } var date = WEF_Utils.parseISO8601( newDataValue.value.time ); if ( isNaN( date ) ) { switchDataType( 'time', newDataValue ); return; } date = new Date( date ); years.val( date.getFullYear() ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( years.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'time', value: { time: WEF_Utils.formatDate( years.val() ), timezone: 0, precision: PRECISION_YEARS, before: 0, after: 0, calendarmodel: WIKIDATA_URI_PREFIX + CALENDAR_GREGORIAN, }, }; }; this.getAsLabel = function() { var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_time_years' ).text( years.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'time', this.getDataValue(), span ); return span; }; years.change( changeF ); years.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'time-centuries' ) { ( function() { selectDateTimePrecision.appendTo( this.mainElement ); var centuries = $( document.createElement( 'input' ) ).attr( 'type', 'number' ).attr( 'step', '1' ).appendTo( this.mainElement ); this.setDataValue = function( newDataValue ) { if ( !/^[\\+\\-][0-9]{1,4}\-/.test( newDataValue.value.time ) ) { switchDataType( 'time', newDataValue ); return; } var date = WEF_Utils.parseISO8601( newDataValue.value.time ); if ( isNaN( date ) ) { switchDataType( 'time', newDataValue ); return; } date = new Date( date ); var year = date.getUTCFullYear(); var century; if ( date.getUTCFullYear() < 0 ) { century = Math.floor( ( Math.abs( year ) - 1 ) / 100 ) + 1; } else { century = Math.floor( ( year - 1 ) / 100 ) + 1; } centuries.val( century ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( centuries.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'time', value: { time: WEF_Utils.formatCentury( centuries.val() ), timezone: 0, precision: PRECISION_CENTURIES, before: 0, after: 0, calendarmodel: WIKIDATA_URI_PREFIX + CALENDAR_GREGORIAN, }, }; }; this.getAsLabel = function() { var century = centuries.val(); var str; if ( century === 0 ) { str = '0'; } else { if ( century < 0 ) { str = WEF_Utils.toRoman( Math.abs( century ) ) + " BC"; } else { str = WEF_Utils.toRoman( century ) + " AD"; } } return $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_time_centuries' ).text( str ); }; centuries.change( changeF ); centuries.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'url' ) { ( function() { var input = $( document.createElement( 'input' ) ).attr( 'type', 'url' ).addClass( 'wef_url' ).appendTo( this.mainElement ); this.setDataValue = function( newDataValue ) { input.val( WEF_Utils.urlNice( newDataValue.value ) ); }; try { if ( typeof options === 'object' && typeof options.check === 'object' ) { input.attr( 'pattern', WEF_Utils.regexpGetHtmlPattern( options.check ) ); } } catch ( err ) { mw.log.warn( 'Unable to attach check pattern to input: ' + err ); } this.hasValue = function() { return !WEF_Utils.isEmpty( input.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } return { type: 'string', value: WEF_Utils.urlUnnice( input.val() ), }; }; this.getAsLabel = function() { var span = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label_url' ).text( input.val() ); if ( this.hasValue() ) WEF_Utils.formatValueRemotely( 'url', this.getDataValue(), span ); return span; }; input.change( changeF ); input.keyup( changeF ); } ).call( this ); } else if ( editorDataType === 'wikibase-item' ) { ( function() { var inputClass = ( WEF_Utils.isEmpty( options ) || !$.isFunction( options.inputClass ) ) ? WEF_ItemInput : options.inputClass; var table = $( document.createElement( 'table' ) ).addClass( 'wef_wikibase-item_table' ).appendTo( snakValueEditor.mainElement ); var tr = $( document.createElement( 'tr' ) ).addClass( 'wef_wikibase-item_tr' ).appendTo( table ); var input = new inputClass().appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_wikibase-item_td_input' ).appendTo( tr ) ); this.setDataValue = function( newDataValue ) { this.setDataValueImpl( WEF_Utils.getEntityIdFromDatavalue( newDataValue ) ); }; this.setDataValueImpl = function( entityId ) { input.val( entityId ); }; this.hasValue = function() { return !WEF_Utils.isEmpty( input.val() ); }; this.getDataValue = function() { if ( !this.hasValue() ) { throw new Error( 'No value' ); } var dataValue = {}; if ( !WEF_Utils.isEmpty( input.val() ) ) { dataValue.value = { 'entity-type': 'item', 'numeric-id': Number( input.val().substr( 1 ) ), }; } dataValue.type = 'wikibase-entityid'; return dataValue; }; this.getAsLabel = function() { var entityId = input.val(); if ( WEF_Utils.isEmpty( entityId ) ) { return $( document.createElement( 'span' ) ); } var result = $( document.createElement( 'span' ) ); result.text( '(' + entityId + ')' ); wef_LabelsCache.getOrQueue( entityId, function( label, description ) { result.text( label + ' (' + entityId + ')' ); result.attr( 'title', description ); } ); return result; }; /** @type {WEF_SelectEditor} */ var selectCreateEditor = null; var selectEditEditor = null; var createOrEditButton = $( document.createElement( 'div' ) ).css( 'cursor', 'pointer' ).addClass( 'wef_wikibase-item_button' ).appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_wikibase-item_td_button wef_button_cell' ).appendTo( tr ) ); createOrEditButton.button( { icons: { primary: 'ui-icon-pencil' }, text: false, label: wef_Editors_i18n.buttonCreateOrEdit, } ); $( this ).on( 'change', function() { if ( selectCreateEditor != null ) selectCreateEditor.hide(); if ( selectEditEditor != null ) selectEditEditor.hide(); } ); createOrEditButton.click( function() { var entityId = input.val(); if ( WEF_Utils.isEmpty( entityId ) ) { if ( selectCreateEditor == null ) { selectCreateEditor = new WEF_SelectEditor( createOrEditButton, wef_Editors_i18n.buttonCreateOrEditPrefixCreate, function( id, editor ) { var d = editor.edit( false, null ); d.done( function( newEntityId ) { if ( !WEF_Utils.isEmpty( newEntityId ) ) { snakValueEditor.setDataValueImpl( newEntityId ); wef_LabelsCache.receiveLabels(); } WEF_Utils.purgeAsync(); } ); } ); selectCreateEditor.show(); } else { selectCreateEditor.toggle(); } } else { if ( selectEditEditor == null ) { selectEditEditor = new WEF_SelectEditor( createOrEditButton, wef_Editors_i18n.buttonCreateOrEditPrefixEdit, function( id, editor ) { var d = editor.edit( false, entityId ); d.done( function() { WEF_Utils.purgeAsync(); } ); } ); selectEditEditor.show(); } else { selectEditEditor.toggle(); } } } ); var onWikidata = $( document.createElement( 'a' ) ).css( 'cursor', 'pointer' ).attr( 'target', '_blank' ).addClass( 'wef_wikibase-item_button' ).appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_wikibase-item_td_button wef_button_cell' ).appendTo( tr ) ); onWikidata.button( { icons: { primary: 'ui-icon-extlink' }, text: false, label: wef_Editors_i18n.buttonOnWikidata, } ); $( this ).on( 'change', function() { var entityId = input.val(); if ( !WEF_Utils.isEmpty( entityId ) ) { onWikidata.attr( 'href', '//www.wikidata.org/wiki/' + entityId ); onWikidata.button( 'enable' ); } else { onWikidata.attr( 'href', '' ); onWikidata.button( 'disable' ); } } ); input.change( changeF ); input.keyup( changeF ); } ).call( this ); } else { throw new Error( 'Unsupported data type: ' + editorDataType ); } if ( typeof initialDataValue !== 'undefined' ) { this.setDataValue( initialDataValue ); } else { changeF(); } }; WEF_SnakValueEditor.prototype.hide = function() { this.mainElement.hide(); }; WEF_SnakValueEditor.prototype.show = function() { this.mainElement.show(); }; /** * Creates input field that used to display or input Wikidata items */ WEF_ItemInput = function( options ) { var DATA_ENTITY_ID = 'value-entity-id'; var DATA_ENTITY_LABEL = 'value-entity-label'; var input = $( document.createElement( 'input' ) ).attr( 'type', 'text' ).addClass( 'wef_item_input' ); this.val = function( entityId ) { if ( typeof entityId === 'undefined' ) { // return current value return input.data( DATA_ENTITY_ID ); } // or set value input.data( DATA_ENTITY_ID, entityId ); input.data( DATA_ENTITY_LABEL, '' ); input.val( '(' + entityId + ')' ); wef_LabelsCache.getOrQueue( entityId, function( label, description ) { if ( input.data( DATA_ENTITY_ID ) === entityId ) { // we need to be sure user didn't start to edit field if ( input.val() === '(' + entityId + ')' || input.val() === input.data( DATA_ENTITY_LABEL ) + ' (' + entityId + ')' ) { input.data( DATA_ENTITY_LABEL, label ); input.val( label + ' (' + entityId + ')' ); input.attr( 'title', description ); } } } ); input.change(); }; input.autocomplete( { source: function( request, response ) { var term = request.term; $.ajax( { dataType: 'json', url: WEF_Utils.getWikidataApiPrefix() // + '&action=wbsearchentities' // + '&language=' + encodeURIComponent( mw.config.get( 'wgUserLanguage' ) ) // + '&limit=15' // + '&search=' + encodeURIComponent( term ), } ).done( function( result ) { var list = []; $.each( result.search, function( index, entity ) { var item = new WEF_ItemInput_Item( entity.id, entity.label ); list.push( item ); } ); response( list ); // just in case everything in cache already wef_LabelsCache.receiveLabels(); } ); }, select: function( event, ui ) { /** @type {WEF_ItemInput_Item} */ var item = ui.item; var input = $( event.target ); var entityId = item.entityId; var label = wef_LabelsCache.getLabel( entityId, true ); var description = wef_LabelsCache.getDescription( entityId, false ); input.data( DATA_ENTITY_ID, entityId ); input.data( DATA_ENTITY_LABEL, label ); input.val( label ); if ( !WEF_Utils.isEmpty( description ) ) { input.attr( 'title', description ); } else { input.removeAttr( 'title' ); } input.change(); return false; }, } ); input.data( 'autocomplete' )._renderItem = /** * @param ul * @param {WEF_ItemInput_Item} * item */ function( ul, item ) { return $( document.createElement( 'li' ) ).append( item.a ).data( 'item.autocomplete', item ).appendTo( ul ); }; input.focus( function() { var id = input.data( DATA_ENTITY_ID ); var label = input.data( DATA_ENTITY_LABEL ); if ( typeof id === 'undefined' || typeof label === 'undefined' ) { input.val( '' ); input.removeData( DATA_ENTITY_ID ); input.removeData( DATA_ENTITY_LABEL ); } else { input.val( label ); } input.change(); } ); input.blur( function() { var id = input.data( DATA_ENTITY_ID ); var label = input.data( DATA_ENTITY_LABEL ); var currentVal = input.val(); if ( currentVal === label ) { input.val( label + ' (' + id + ')' ); } else { input.val( '' ); input.removeData( DATA_ENTITY_ID ); input.removeData( DATA_ENTITY_LABEL ); } input.change(); } ); this.addClass = function() { input.addClass.apply( input, arguments ); return this; }; this.appendTo = function() { input.appendTo.apply( input, arguments ); return this; }; this.change = input.change.bind( input ); this.keyup = input.keyup.bind( input ); }; WEF_ItemInput_Item = function( entityId, label ) { this.entityId = entityId; var labelWrapper = $( '<strong></strong>' ); wef_LabelsCache.localizeLabel( labelWrapper, entityId ); var entityIdWrapper = $( '<span style="color: darkgray;">' + entityId + '</span>' ); var descriptionWrapper = $( '<span></span>' ); wef_LabelsCache.localizeDescription( descriptionWrapper, entityId ); var space = $( '<span> </span>' ); var br = $( '<br>' ); var a = this.a = $( '<a></a>' ); a.append( labelWrapper ); a.append( space ); a.append( entityIdWrapper ); a.append( br ); a.append( descriptionWrapper ); }; /** * Creates select field that has predefined number of values, but also support * extending values based on load external values. Uses {@link WEF_LabelsCache} * and JQuery autoselect */ WEF_ItemSelect = function() { var select = $( document.createElement( 'select' ) ).addClass( 'wef_item_select' ); this.select = select; this.addOption = function( entityId ) { if ( typeof entityId === 'undefined' || entityId === null ) { throw new Error( 'incorrect entity ID: ' + entityId ); } var option = $( document.createElement( 'option' ) ).appendTo( select ); option.attr( 'value', entityId ); option.text( entityId ); wef_LabelsCache.getOrQueue( entityId, function( label, description ) { option.text( label ); option.attr( 'title', description ); } ); return option; }; this.val = function( value ) { if ( typeof value === 'undefined' ) { return select.val(); } else if ( value === null ) { select.prop( 'selectedIndex', -1 ); } else { select.val( value ); var option = select.find( ':selected' ); if ( option.length !== 0 ) { return option; } var newOption = this.addOption( value ); select.val( value ); return newOption; } }; }; /** * Creates input field to input language code based on $.uls.data.languages list */ WEF_LanguageInput = ( function() { var availableLanguagesCache; var getAvailableLanguages = function() { if ( typeof availableLanguagesCache === 'undefined' ) { var availableLanguagesCache = []; $.each( $.uls.data.languages, function( languageCode, languageOptions ) { var languageTitle = languageOptions[2]; var auctocompleteObject = { label: languageCode + ' — ' + languageTitle, value: languageCode, }; availableLanguagesCache.push( auctocompleteObject ); } ); } return availableLanguagesCache; } return function() { var input = $( document.createElement( 'input' ) ).addClass( 'wef_language_select' ); input.autocomplete( { source: getAvailableLanguages(), } ); this.appendTo = input.appendTo.bind( input ); this.change = input.change.bind( input ); this.val = input.val.bind( input ); }; } )(); /** @class */ var WEF_SelectSnakType = function() { var i18n = wef_Editors_i18n; var select = $( document.createElement( 'select' ) ).addClass( 'wef-snaktypeselector-menu' ).attr( 'size', 3 ); select.hide(); $( document.body ).append( select ); var _this = this; function changeF() { var value = _this.val(); if ( value !== null ) { _this.hide(); _this.listener( value ); } } $( document.createElement( 'option' ) ).attr( 'value', 'value' ).text( i18n.snakTypeValue ).attr( 'title', i18n.snakTypeValueTitle ).appendTo( select ); $( document.createElement( 'option' ) ).attr( 'value', 'novalue' ).text( i18n.snakTypeNoValue ).attr( 'title', i18n.snakTypeNoValueTitle ).appendTo( select ); $( document.createElement( 'option' ) ).attr( 'value', 'somevalue' ).text( i18n.snakTypeSomeValue ).attr( 'title', i18n.snakTypeSomeValueTitle ).appendTo( select ); select.click( changeF ); select.change( changeF ); this.listener = function( value ) { // no ops }; this.val = function( value ) { if ( typeof value === 'undefined' ) { return select.val(); } select.val( value ); }; this.text = function() { var option = select.find( ':selected' ); if ( option.length !== 0 ) { return option.text(); } return null; }; this.visible = false; this.hide = function() { this.visible = false; select.hide(); }; this.show = function( anchor, value, listener ) { this.val( value ); anchor.after( select ); select.show().position( { my: 'left top', at: 'right top', of: anchor, } ); this.listener = listener; this.visible = true; }; }; window.wef_selectSnakType = new WEF_SelectSnakType(); WEF_SnakEditor = function( parent, options ) { if ( WEF_Utils.isEmpty( parent ) ) { throw new Error( 'parent is empty or not specified' ); } this.options = options; var snakEditor = this; this.snakTypeMode = null; this.valueEditor = null; this.propertyId = null; this._butttonSelectSnakType = $( document.createElement( 'button' ) ).addClass( 'wef_select_snak_type_button' ); this._butttonSelectSnakType.button( { icons: { primary: 'ui-icon-triangle-1-e' }, text: false, label: wef_Editors_i18n.buttonSelectSnakType, } ).click( function() { if ( wef_selectSnakType.visible && wef_selectSnakType.initiator === this ) { wef_selectSnakType.hide(); } else { wef_selectSnakType.initiator = this; wef_selectSnakType.show( snakEditor._butttonSelectSnakType, snakEditor.snakTypeMode, function( value ) { snakEditor.switchToSnakType( value ); } ); } } ); // JQuery parent element this.table = $( document.createElement( 'table' ) ).addClass( 'wef_snak_table' ).appendTo( parent ); this._tr = $( document.createElement( 'tr' ) ).appendTo( this.table ); this._td1 = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( this._tr ); this._td2 = $( document.createElement( 'td' ) ).addClass( 'wef_snak_table_value_editor_cell' ).appendTo( this._tr ); this._snakTypeLabel = $( document.createElement( 'span' ) ).addClass( 'wef_snak_type_label' ).appendTo( this._td2 ).hide(); this._td1.append( this._butttonSelectSnakType ); this.hiddenBehindLabel = false; this._jThis = $( this ); }; WEF_SnakEditor.prototype._change = function() { this._jThis.trigger( 'change' ); }; WEF_SnakEditor.prototype.hasData = function() { return this.snakTypeMode !== 'value' || this.valueEditor.hasValue(); }; WEF_SnakEditor.prototype.hasValue = function() { return this.snakTypeMode === 'value' && this.valueEditor.hasValue(); }; WEF_SnakEditor.prototype.hideBehindLabel = function() { var label = $( document.createElement( 'span' ) ).addClass( 'wef_snak_replacement_label' ); label.css( 'cursor', 'pointer' ); if ( this.snakTypeMode === 'value' ) { label.append( this.valueEditor.getAsLabel() ); } else { label.text( wef_selectSnakType.text() ); } this.table.before( label ); this.table.hide(); var snakEditor = this; snakEditor.hiddenBehindLabel = true; label.click( function() { label.remove(); snakEditor.table.show(); snakEditor.hiddenBehindLabel = false; } ); return label; }; WEF_SnakEditor.prototype.initEmptyWithDataType = function( propertyId, dataType, editorDataType ) { this.propertyId = propertyId; this.snakTypeMode = 'value'; this.valueEditor = new WEF_SnakValueEditor( this._td2, dataType, editorDataType, undefined, this.options ); this._initValueEditor(); }; WEF_SnakEditor.prototype.initEmptyWithPropertyId = function( propertyId ) { this.propertyId = propertyId; this.snakTypeMode = 'novalue'; this.switchToSnakType( 'value' ); }; WEF_SnakEditor.prototype._initValueEditor = function() { var snakEditor = this; $( this.valueEditor ).change( function() { snakEditor._change(); } ); }; WEF_SnakEditor.prototype.initWithValue = function( snak ) { if ( typeof snak.property === 'undefined' ) { throw new Error( 'Snak does not specify property ID' ); } if ( typeof snak.snaktype === 'snaktype' ) { throw new Error( 'Snak does not specify snak type' ); } this.propertyId = snak.property; this.snakTypeMode = snak.snaktype; if ( snak.snaktype === 'value' ) { if ( typeof snak.datatype === 'undefined' ) { throw new Error( 'Snak contains value, but does not specify data type' ); } if ( typeof snak.datavalue === 'undefined' ) { throw new Error( 'Snak type is value, but value does not present' ); } this.valueEditor = new WEF_SnakValueEditor( this._td2, snak.datatype, undefined, snak.datavalue, this.options ); this._initValueEditor(); } else { this._showSnakTypeLabel( snak.snaktype ); } this._change(); }; /** @return {string} */ WEF_SnakEditor.prototype.getDataType = function() { if ( this.snakTypeMode !== 'value' ) { throw new Error( 'data type make sence only when snak type is "value"' ); } return this.valueEditor.dataDataType; }; WEF_SnakEditor.prototype.getDataValue = function() { return this.valueEditor.getDataValue(); }; WEF_SnakEditor.prototype.remove = function() { this.table.remove(); this.valueEditor = null; this.parent = null; }; WEF_SnakEditor.prototype.setSnakValue = function( snak ) { if ( typeof snak.property === 'undefined' ) { throw new Error( 'Snak does not specify property ID' ); } if ( typeof snak.snaktype === 'snaktype' ) { throw new Error( 'Snak does not specify snak type' ); } this.propertyId = snak.property; this.switchToSnakType( snak.snaktype ); if ( snak.snaktype === 'value' ) { this.valueEditor.setDataValue( snak.datavalue ); } this._change(); }; WEF_SnakEditor.prototype._showSnakTypeLabel = function( snakType ) { if ( snakType === 'novalue' ) { this._snakTypeLabel.text( wef_Editors_i18n.snakTypeNoValue ).attr( 'title', wef_Editors_i18n.snakTypeNoValueTitle ); } else if ( snakType === 'somevalue' ) { this._snakTypeLabel.text( wef_Editors_i18n.snakTypeSomeValue ).attr( 'title', wef_Editors_i18n.snakTypeSomeValueTitle ); } else { this._snakTypeLabel.text( '' ).attr( 'title', '' ); } this._snakTypeLabel.show(); }; WEF_SnakEditor.prototype.switchToSnakType = function( snakType ) { var oldSnakType = this.snakTypeMode; if ( oldSnakType === snakType ) { return; } this.snakTypeMode = snakType; if ( this.valueEditor !== null ) { this.valueEditor.hide(); } var snakEditor = this; if ( snakType === 'value' ) { if ( this.valueEditor === null ) { wef_TypesCache.getPropertyType( snakEditor.propertyId, function( dataType ) { snakEditor._snakTypeLabel.hide(); snakEditor.valueEditor = new WEF_SnakValueEditor( snakEditor._td2, dataType, undefined, undefined, snakEditor.options ); snakEditor._initValueEditor(); snakEditor._change(); }, function( failureReason ) { alert( "Can't change snak value type bacause property data type is unknown: " + failureReason ); snakEditor.snakTypeMode = oldSnakType; } ); } else { this._snakTypeLabel.hide(); this.valueEditor.show(); } } else { this._showSnakTypeLabel( snakType ); this._change(); } }; /** * Returns the array of claims for specified definition from entity * * @param definition * {WEF_Definition} * @param claims * Wikidata entity JSON * @returns {WEF_Claim[]} */ window.WEF_filterClaims = function( definition, claims ) { var isPropertyEditor = /^P\d+$/i.test( definition.code ); var isQualifierEditor = /^P\d+\[Q\d+\]\/P\d+$/i.test( definition.code ); /* Main property ID */ /** @type {string} */ var propertyId; /* Required property value */ var propertyValue; if ( isPropertyEditor ) { var test = definition.code.match( /^P(\d+)$/i ); propertyId = 'P' + test[1]; propertyValue = undefined; } else if ( isQualifierEditor ) { var test = definition.code.match( /^P(\d+)\[Q(\d+)\]\/P(\d+)$/i ); propertyId = 'P' + test[1]; propertyValue = 'Q' + test[2]; } else { throw new Error( 'Unsupported code: ' + definition.code ); } if ( typeof claims === 'undefined' || typeof claims[propertyId] === 'undefined' ) { return []; } /** @type {WEF_Claim[]} */ var byPropertyId = claims[propertyId]; if ( isPropertyEditor ) { return byPropertyId; } if ( isQualifierEditor ) { var result = []; $.each( byPropertyId, function( index, claim ) { var entityId = WEF_Utils.getEntityIdFromClaim( claim ); if ( typeof entityId != 'undefined' && entityId === propertyValue ) { result.push( claim ); } } ); return result; } throw new Error( 'Illegal state' ); }; WEF_QualifierEditor = function( parent, propertyId, onRemove ) { /** @type {string} */ this.propertyId = null; /** @type {WEF_SnakEditor} */ this.snakEditor = null; /** @type {WEF_Snak} */ this.wikidataSnak = null; /** @type {string} */ this.wikidataOldValue = null; this.qualifierRow = $( document.createElement( 'tr' ) ).appendTo( parent ); this.qualifierEditCell = $( document.createElement( 'td' ) ).addClass( 'wef_qualifiers_edit_cell' ).appendTo( this.qualifierRow ); this.qualifierRemoveCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( this.qualifierRow ); this._addRemoveButton( this.qualifierRemoveCell ); this._onRemove = onRemove; }; /** * @param claimData * {WEF_Claim} * @return {Boolean} */ WEF_QualifierEditor.prototype.collectUpdates = function( claimData ) { if ( this.hasData() ) { var snakValue = this.getSnakValue(); WEF_Utils.appendToNamedMap( claimData, 'qualifiers', this.propertyId, snakValue ); return JSON.stringify( snakValue ) !== this.wikidataOldValue; } else { /* * just ignore it and do not add to claim -- it will be removed as * "missing" one */ return this.wikidataOldValue !== null; } }; WEF_QualifierEditor.prototype.hasData = function() { return this.propertyId != null && this.snakEditor.hasData(); }; WEF_QualifierEditor.prototype.initWithValue = function( qualifierSnak ) { this.wikidataSnak = qualifierSnak; this.propertyId = qualifierSnak.property; this.snakEditor = new WEF_SnakEditor( this.qualifierEditCell ); this.snakEditor.initWithValue( qualifierSnak ); this.wikidataOldValue = this.hasData() ? JSON.stringify( this.getSnakValue() ) : null; var qualifierEditor = this; var label = this.snakEditor.hideBehindLabel(); label.click( function() { $( qualifierEditor ).trigger( 'afterShow' ); } ); $( qualifierEditor ).trigger( 'afterHide' ); }; /** Create empty editor but hide it behind replacement label as well */ WEF_QualifierEditor.prototype.initWithEmpty = function( propertyId, dataType, editorDataType ) { this.wikidataSnak = null; this.propertyId = propertyId; this.wikidataOldValue = null; this.snakEditor = new WEF_SnakEditor( this.qualifierEditCell ); this.snakEditor.initEmptyWithDataType( propertyId, dataType, editorDataType ); }; /** @return {string} */ WEF_QualifierEditor.prototype.getHash = function() { return this.wikidataSnak != null ? this.wikidataSnak.hash : null; }; WEF_QualifierEditor.prototype.getSnakValue = function() { if ( !this.hasData() ) { throw new Error( 'no data' ); } var snak = {}; if ( this.wikidataSnak !== null ) { snak.hash = this.wikidataSnak.hash; } snak.snaktype = this.snakEditor.snakTypeMode; snak.property = this.propertyId; if ( this.snakEditor.snakTypeMode === 'value' ) { snak.datatype = this.snakEditor.getDataType(); snak.datavalue = this.snakEditor.getDataValue(); } return snak; }; WEF_QualifierEditor.prototype.clear = function() { this.propertyId = null; this.snakEditor = null; this.qualifierRow.remove(); }; WEF_QualifierEditor.prototype._addRemoveButton = function( target ) { var qualifierEditor = this; var button = $( document.createElement( 'button' ) ).attr( 'type', 'button' ).button( { icons: { primary: 'ui-icon-trash' }, text: false, label: wef_Editors_i18n.buttonRemoveQualifier, } ).click( function() { qualifierEditor._onRemove( qualifierEditor ); } ).addClass( 'wef_qualifier_button' ).appendTo( target ); $( this ).on( 'afterHide', function() { button.hide(); } ); $( this ).on( 'afterShow', function() { button.show(); } ); }; WEF_SelectableQualifierEditor = function( parent, qualifierDefinitions, onRemove ) { /** @type {string} */ this.propertyId = null; /** @type {WEF_SnakEditor} */ this.snakEditor = null; /** @type {WEF_Snak} */ this.wikidataSnak = null; /** @type {string} */ this.wikidataOldValue = null; var qualifiedEditor = this; this.qualifierRow = $( document.createElement( 'tr' ) ).appendTo( parent ); /** @type {WEF_ItemSelect} */ var qualifierSelect = this.qualifierSelect = new WEF_ItemSelect(); qualifierSelect.select.appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_qualifiers_select_cell' ).appendTo( this.qualifierRow ) ); this.qualifierEditCell = $( document.createElement( 'td' ) ).addClass( 'wef_qualifiers_edit_cell' ).appendTo( this.qualifierRow ); this.qualifierRemoveCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( this.qualifierRow ); if ( $.isArray( qualifierDefinitions ) ) { $.each( qualifierDefinitions, function( index, qualifierDefinition ) { var code = qualifierDefinition.code; qualifierSelect.addOption( code ); if ( !WEF_Utils.isEmpty( qualifierDefinition.datatype ) ) { wef_TypesCache.putInCache( code, qualifierDefinition.datatype ); } } ); } // do not select the first qualifierSelect.val( null ); qualifierSelect.hideBehindLabel = function() { var label = $( document.createElement( 'span' ) ); label.css( 'cursor', 'pointer' ); var code = qualifierSelect.val(); label.text( '(' + qualifierSelect.val() + '): ' ); wef_LabelsCache.getOrQueue( code, function( newLabel, newDescription ) { label.text( newLabel + ': ' ); label.attr( 'title', newDescription ); } ); qualifierSelect.select.before( label ); qualifierSelect.select.hide(); label.click( function() { label.remove(); qualifierSelect.select.show(); } ); return label; }; qualifierSelect.select.change( function() { var newPropertyId = qualifierSelect.val(); if ( newPropertyId != null && qualifiedEditor.propertyId != newPropertyId ) { qualifiedEditor._onPropertySelect( newPropertyId ); } } ); /** @type {function} */ this._onRemove = onRemove; this._addRemoveButton( this.qualifierRemoveCell ); }; WEF_SelectableQualifierEditor.prototype = Object.create( WEF_QualifierEditor.prototype ); WEF_SelectableQualifierEditor.prototype.initWithValue = function( qualifierSnak ) { var qualifierEditor = this; this.wikidataSnak = qualifierSnak; this.propertyId = qualifierSnak.property; this.qualifierSelect.val( qualifierSnak.property ); this.snakEditor = new WEF_SnakEditor( this.qualifierEditCell ); this.snakEditor.initWithValue( qualifierSnak ); // remember old value this.wikidataOldValue = this.hasData() ? JSON.stringify( this.getSnakValue() ) : null; var selectLabel = this.qualifierSelect.hideBehindLabel(); var editorLabel = this.snakEditor.hideBehindLabel(); this.qualifierRemoveCell.css( 'visibility', 'hidden' ); $( qualifierEditor ).trigger( 'afterHide' ); var firstTime = true; this.qualifierRow.click( function( evt ) { if ( firstTime ) { firstTime = false; qualifierEditor.qualifierRemoveCell.css( 'visibility', 'inherit' ); var target = $( evt.target ); if ( !selectLabel.is( target ) && !$.contains( selectLabel[0], target ) ) { selectLabel.click(); } if ( !editorLabel.is( target ) && !$.contains( editorLabel[0], target ) ) { editorLabel.click(); } $( qualifierEditor ).trigger( 'afterShow' ); } } ); }; /* Called from drop-down select */ WEF_SelectableQualifierEditor.prototype._onPropertySelect = function( newPropertyId ) { this.propertyId = newPropertyId; // do we have qualifier input already? if ( this.snakEditor == null ) { this.snakEditor = new WEF_SnakEditor( this.qualifierEditCell ); this.snakEditor.initEmptyWithPropertyId( newPropertyId ); } else { if ( this.snakEditor.propertyId === newPropertyId ) { // leave as it is } else { this.snakEditor.remove(); this.snakEditor = new WEF_SnakEditor( this.qualifierEditCell ); this.snakEditor.initEmptyWithPropertyId( newPropertyId ); } } }; /** @const */ var PROPERTIES_OF_REFERENCE = []; PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P248', // specified in datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P50', // author datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P1476', // title datatype: 'monolingualtext', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P1680', // subtitle datatype: 'monolingualtext', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P393', // editor datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P1433', // publication datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P123', // publisher datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P478', // volume datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P433', // issue datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P792', // chapter datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P958', // section datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P304', // pages datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P143', // imported from datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P813', // date retrieved datatype: 'time', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P854', // URL datatype: 'url', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P1065', // archive URL datatype: 'url', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P212', // ISBN 13 datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P957', // ISBN 10 datatype: 'string', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P1480', // sourcing circumstances datatype: 'wikibase-item', } ) ); PROPERTIES_OF_REFERENCE.push( new WEF_Definition( { code: 'P387', // citation datatype: 'string', } ) ); /** @class */ WEF_ClaimReferenceEditor = function( parentTableElement ) { "use strict"; var claimReferenceEditor = this; this.parentTableElement = parentTableElement; this.snaksEditors = []; this.wikidataHash = null; this.wikidataOldSnaksStr = null; this.lastRow = $( document.createElement( 'tr' ) ).appendTo( parentTableElement ); var newSnakTypeSelect = new WEF_ItemSelect(); $.each( PROPERTIES_OF_REFERENCE, function( index, propertyDefinition ) { var code = propertyDefinition.code; newSnakTypeSelect.addOption( code ); wef_TypesCache.putInCache( code, propertyDefinition.datatype ); } ); newSnakTypeSelect.val( null ); newSnakTypeSelect.select.appendTo( $( document.createElement( 'td' ) ).addClass( 'wef_reference_select_cell' ).appendTo( this.lastRow ) ); newSnakTypeSelect.select.change( function() { var newPropertyId = newSnakTypeSelect.val(); if ( newPropertyId != null ) { var snakEditor = new WEF_SelectableQualifierEditor( claimReferenceEditor.parentTableElement, PROPERTIES_OF_REFERENCE, function( removedEditor ) { claimReferenceEditor._onSnakEditorRemove( removedEditor ); } ); snakEditor.qualifierSelect.val( newPropertyId ); snakEditor._onPropertySelect( newPropertyId ); claimReferenceEditor.snaksEditors.push( snakEditor ); newSnakTypeSelect.val( null ); claimReferenceEditor.moveSelectToLastRow(); } } ); }; /** * Reappend empty row with only-for-select drop-down list to the end of the * table */ WEF_ClaimReferenceEditor.prototype.moveSelectToLastRow = function() { "use strict"; this.lastRow.detach(); this.lastRow.appendTo( this.parentTableElement ); }; WEF_ClaimReferenceEditor.prototype.load = function( reference ) { "use strict"; this.wikidataHash = typeof reference.hash !== 'undefined' ? reference.hash : null; this.wikidataOldSnaksStr = typeof reference.snaks !== 'undefined' ? JSON.stringify( reference.snaks ) : null; var claimReferenceEditor = this; $.each( reference.snaks, function( propertyId, propertySnaks ) { $.each( propertySnaks, function( i, snak ) { var snakEditor = new WEF_SelectableQualifierEditor( claimReferenceEditor.parentTableElement, PROPERTIES_OF_REFERENCE, function( removedEditor ) { claimReferenceEditor._onSnakEditorRemove( removedEditor ); } ); snakEditor.initWithValue( snak ); claimReferenceEditor.snaksEditors.push( snakEditor ); } ); } ); this.moveSelectToLastRow(); }; WEF_ClaimReferenceEditor.prototype.collect = function() { "use strict"; var newReference = {}; var snaksOrder = []; if ( this.wikidataHash !== null ) { newReference.hash = this.wikidataHash; } $.each( this.snaksEditors, function( i, snakEditor ) { if ( snakEditor.hasData() ) { var propertyId = snakEditor.propertyId; WEF_Utils.appendToNamedMap( newReference, 'snaks', propertyId, snakEditor.getSnakValue() ); if ( $.inArray( propertyId, snaksOrder ) === -1 ) { snaksOrder.push( propertyId ); } } } ); if ( !WEF_Utils.isEmpty( newReference.snaks ) ) { newReference["snaks-order"] = snaksOrder; return newReference; } return; }; WEF_ClaimReferenceEditor.prototype._onSnakEditorRemove = function( removedEditor ) { "use strict"; removedEditor.qualifierRow.remove(); this.snaksEditors = $.grep( this.snaksEditors, function( value ) { return value != removedEditor; } ); }; /** @class */ WEF_ClaimReferencesEditor = function() { "use strict"; var claimReferencesEditor = this; var i18n = wef_Editors_i18n; this.parent = $( document.createElement( 'div' ) ).addClass( 'wef_references_editor' ); this.referencesHolder = $( document.createElement( 'div' ) ).appendTo( this.parent ); var referencesTable = $( document.createElement( 'div' ) ).addClass( 'wef_reference_editor_table' ).appendTo( this.parent ); var part1 = $( document.createElement( 'div' ) ).addClass( 'wef_reference_editor_column' ).appendTo( referencesTable ); $( document.createElement( 'span' ) ).text( i18n.sourcesLabelAddUsedReferences ).appendTo( part1 ); this.addReferenceHolder = $( document.createElement( 'ul' ) ).addClass( 'wef_reference_editor_list' ).appendTo( part1 ); this.editors = []; this.parent.dialog( { dialogClass: 'wef_references_editor_dialog', title: i18n.sourcesDialogTitle, autoOpen: false, width: 'auto', maxWidth: 1000, height: 'auto', resizable: true, modal: true, buttons: [ { text: i18n.sourcesButtonAddText, label: i18n.sourcesButtonAddLabel, click: function() { claimReferencesEditor.add(); }, style: 'float: left;', }, { text: i18n.sourcesButtonUpdateLabelsText, label: i18n.sourcesButtonUpdateLabelsLabel, click: function() { wef_LabelsCache.clearCacheAndRequeue(); wef_LabelsCache.receiveLabels(); }, style: 'float: left;', }, { text: i18n.sourcesButtonCloseText, label: i18n.sourcesButtonCloseLabel, click: function() { claimReferencesEditor.parent.dialog( 'close' ); claimReferencesEditor.rememberUsedSources(); }, style: 'float: right;', } ], } ); }; WEF_ClaimReferencesEditor.prototype.add = function() { "use strict"; var div = $( document.createElement( 'table' ) ).addClass( 'wef_reference_editor' ).appendTo( this.referencesHolder ); var claimReferenceEditor = new WEF_ClaimReferenceEditor( div ); // TODO: something like "init with empty?" // claimReferenceEditor.load( reference ); this.editors.push( claimReferenceEditor ); }; WEF_ClaimReferencesEditor.prototype.collect = function() { "use strict"; var result = []; $.each( this.editors, function( i, editor ) { /** @type WEF_ClaimReferenceEditor */ var claimReferenceEditor = editor; var reference = claimReferenceEditor.collect(); if ( !WEF_Utils.isEmpty( reference ) ) { result.push( reference ); } } ); return result; }; WEF_ClaimReferencesEditor.prototype.initAsEmpty = function() { "use strict"; this.loadUsedSources(); wef_LabelsCache.receiveLabels(); }; WEF_ClaimReferencesEditor.prototype.load = function( references ) { "use strict"; var claimReferencesEditor = this; $.each( references, function( i, reference ) { claimReferencesEditor.addReference( reference ); } ); this.loadUsedSources(); wef_LabelsCache.receiveLabels(); }; WEF_ClaimReferencesEditor.prototype.addReference = function( reference ) { var div = $( document.createElement( 'table' ) ).addClass( 'wef_reference_editor' ).appendTo( this.referencesHolder ); var claimReferenceEditor = new WEF_ClaimReferenceEditor( div ); claimReferenceEditor.load( reference ); this.editors.push( claimReferenceEditor ); }; WEF_ClaimReferencesEditor.prototype.loadUsedSources = function() { "use strict"; if ( typeof window.localStorage === 'undefined' || typeof window.localStorage['wef-latest-sources-refs'] === 'undefined' ) return; var claimReferencesEditor = this; try { var remembered = JSON.parse( window.localStorage['wef-latest-sources-refs'] ).slice( 0 ); $.each( remembered, function( i, record ) { var property = 'P' + record[0]; var itemId = Number( record[1] ); var item = 'Q' + itemId; var propertyName = property; var itemName = item; var li = $( document.createElement( 'li' ) ).appendTo( claimReferencesEditor.addReferenceHolder ); var reflink = $( document.createElement( 'a' ) ).addClass( 'wef_reference_editor_ref' ).text( propertyName + ': ' + itemName ).appendTo( li ); wef_LabelsCache.getOrQueue( property, function( label ) { propertyName = label; reflink.text( propertyName + ': ' + itemName ); } ); wef_LabelsCache.getOrQueue( item, function( label ) { itemName = label; reflink.text( propertyName + ': ' + itemName ); } ); reflink.click( function() { li.remove(); var reference = { snaks: {}, }; reference.snaks[property] = [ WEF_Utils.newWikibaseItemSnak( property, 'item', itemId ) ]; claimReferencesEditor.addReference( reference ); } ); } ); } catch ( e ) { mw.log( 'Unable to load latest sources refs from local storage: ' + e ); } }; WEF_ClaimReferencesEditor.prototype.rememberUsedSources = function() { "use strict"; if ( typeof window.localStorage === 'undefined' ) return; var claimReferencesEditor = this; try { var usedSources = []; $.each( this.editors, function( i, claimReferenceEditor ) { var reference = claimReferenceEditor.collect(); claimReferencesEditor._collectSourceRef( reference.snaks, 248, usedSources ); claimReferencesEditor._collectSourceRef( reference.snaks, 143, usedSources ); } ); var remembered = []; try { var stored = window.localStorage['wef-latest-sources-refs']; if ( typeof stored !== 'undefined' ) { remembered = JSON.parse( stored ).slice( 0 ); } } catch ( e ) { mw.log( 'Unknown error trying to restore latest sources refs from local storage: ' + e ); } var newToRemember = usedSources.concat( remembered ).slice( 0, 10 ); // leave unique only var stringified = $.map( newToRemember, function( x ) { return JSON.stringify( x ); } ); newToRemember = $.grep( newToRemember, function( item, i ) { return $.inArray( JSON.stringify( item ), stringified ) === i // / && typeof $.isArray( item ) // && item.length === 2 // && typeof item[0] === 'number' // && typeof item[1] === 'number'; } ); window.localStorage['wef-latest-sources-refs'] = JSON.stringify( newToRemember ); } catch ( e ) { mw.log( 'Unable to update latest sources refs in local storage: ' + e ); } }; WEF_ClaimReferencesEditor.prototype._collectSourceRef = function( snaks, propertyNumberId, usedSources ) { "use strict"; var value = this._getItemId( snaks, 'P' + propertyNumberId ); if ( typeof value !== 'undefined' ) { usedSources.push( [ propertyNumberId, value ] ); } }; WEF_ClaimReferencesEditor.prototype._getItemId = function( snaks, propertyId ) { "use strict"; var hasValue = typeof snaks[propertyId] !== 'undefined' // && snaks[propertyId].length === 1 // && typeof snaks[propertyId][0].datavalue !== 'undefined' // && typeof snaks[propertyId][0].datavalue.value !== 'undefined' // && snaks[propertyId][0].datavalue.value['entity-type'] === 'item'; if ( hasValue ) { var value = Number( snaks[propertyId][0].datavalue.value['numeric-id'] ); if ( !Number.isNaN( value ) ) { return value; } } return undefined; }; WEF_ClaimReferencesEditor.prototype.show = function() { "use strict"; this.parent.dialog( 'open' ); }; /** @class */ WEF_SelectRank = function() { var i18n = wef_Editors_i18n; var select = $( document.createElement( 'select' ) ).addClass( 'wef-claimrankselector-menu' ).attr( 'size', 3 ); select.hide(); $( document.body ).append( select ); var _this = this; function changeF() { var value = _this.val(); if ( value !== null ) { _this.hide(); _this.listener( value ); } } $( document.createElement( 'option' ) ).attr( 'value', WEF_RANK_PREFERRED ).text( i18n.rankPreferredValue ).attr( 'title', i18n.rankPreferredTitle ).appendTo( select ); $( document.createElement( 'option' ) ).attr( 'value', WEF_RANK_NORMAL ).text( i18n.rankNormalValue ).attr( 'title', i18n.rankNormalTitle ).appendTo( select ); $( document.createElement( 'option' ) ).attr( 'value', WEF_RANK_DEPRECATED ).text( i18n.rankDeprecatedValue ).attr( 'title', i18n.rankDeprecatedTitle ).appendTo( select ); select.click( changeF ); select.change( changeF ); this.listener = function( value ) { // no ops }; this.val = function( value ) { if ( typeof value === 'undefined' ) { return select.val(); } select.val( value ); }; this.text = function() { var option = select.find( ':selected' ); if ( option.length !== 0 ) { return option.text(); } return null; }; this.visible = false; this.hide = function() { this.visible = false; select.hide(); }; this.show = function( anchor, value, listener ) { this.val( value ); anchor.after( select ); select.show().position( { my: 'left top', at: 'right top', of: anchor, } ); this.listener = listener; this.visible = true; }; }; window.wef_selectRank = new WEF_SelectRank(); /** @class */ var WEF_LabelsEditor = function() { "use strict"; var i18n = wef_Editors_i18n; this.placed = false; var labelsEditor = this; this.oldLabels = {}; this.oldDescriptions = {}; // this.oldAliases = {}; // key is language this.dataLabels = {}; this.dataDescriptions = {}; // this.dataAliases = {}; this.currentLanguage = null; this.fieldset = $( document.createElement( 'fieldset' ) ).addClass( 'wef_fieldset' ).addClass( 'wef-labels-editor' ); this.legend = $( document.createElement( 'legend' ) ).text( i18n.labelLabels + ':\u00A0\u00A0\u00A0' ).appendTo( this.fieldset ); this.langSelect = $( document.createElement( 'select' ) ).appendTo( this.legend ); var table = $( document.createElement( 'table' ) ).addClass( 'wef-table' ).addClass( 'wef-labels-editor-table' ).appendTo( this.fieldset ); var tr1 = $( document.createElement( 'tr' ) ).appendTo( table ); $( document.createElement( 'th' ) ).addClass( 'wef-labels-editor-th' ).text( i18n.labelLabel ).appendTo( tr1 ); this.inputLabel = $( document.createElement( 'input' ) ).addClass( 'wef-labels-editor-label-input' ).appendTo( $( document.createElement( 'td' ) ).addClass( 'wef-labels-editor-label-td' ).appendTo( tr1 ) ); var tr2 = $( document.createElement( 'tr' ) ).appendTo( table ); $( document.createElement( 'th' ) ).addClass( 'wef-labels-editor-th' ).text( i18n.labelDescription ).appendTo( tr2 ); this.inputDescription = $( document.createElement( 'input' ) ).addClass( 'wef-labels-editor-description-input' ).appendTo( $( document.createElement( 'td' ) ).addClass( 'wef-labels-editor-description-td' ).appendTo( tr2 ) ); // var tr3 = $( document.createElement( 'tr' ) ).appendTo( table ); // $( document.createElement( 'th' ) ).text( i18n.labelAliases ).appendTo( // tr3 ); // this.inputAliases = $( document.createElement( 'ul' ) ).appendTo( $( // document.createElement( 'td' ) ).appendTo( tr3 ) ); this.langSelect.change( function() { labelsEditor.switchLanguage(); } ); this.langSelect.change( function() { labelsEditor.switchLanguage(); } ); }; WEF_LabelsEditor.prototype.replaceAll = function( target ) { "use strict"; if ( this.placed === true ) { throw new Error( 'Claims edit table is already placed on the form' ); } this.placed = true; this.fieldset.replaceAll( target ); }; WEF_LabelsEditor.prototype.initAsEmpty = function( currentPageItem ) { "use strict"; var labelsEditor = this; this.oldLabels = {}; this.oldDescriptions = {}; this.dataLabels = {}; this.dataDescriptions = {}; this.currentLanguage = null; var contentLang = mw.config.get( 'wgContentLanguage' ); var userLang = mw.config.get( 'wgUserLanguage' ); if ( currentPageItem && !WEF_Utils.isWikidata() ) { this.dataLabels[contentLang] = mw.config.get( 'wgPageName' ); } var languages = []; if ( contentLang === userLang ) { languages.push( contentLang ); } else { languages.push( userLang ); languages.push( contentLang ); } $.each( languages, function( i, language ) { $( document.createElement( 'option' ) ).attr( 'value', language ).text( language ).appendTo( labelsEditor.langSelect ); } ); this.currentLanguage = null; if ( WEF_Utils.isWikidata() ) { this.langSelect.val( userLang ); } else { this.langSelect.val( contentLang ); } this.switchLanguage(); }; WEF_LabelsEditor.prototype.load = function( entity ) { "use strict"; var labelsEditor = this; // holder for all used laguages var languages = []; if ( typeof entity.labels !== 'undefined' ) { $.each( entity.labels, function( language, label ) { if ( languages.indexOf( language ) === -1 ) { languages.push( language ); } labelsEditor.dataLabels[language] = label.value; } ); } if ( typeof entity.descriptions !== 'undefined' ) { $.each( entity.descriptions, function( language, description ) { if ( languages.indexOf( language ) === -1 ) { languages.push( language ); } labelsEditor.dataDescriptions[language] = description.value; } ); } // if ( typeof entity.aliases !== 'undefined' ) { // $.each( entity.aliases, function( language, langAliases ) { // if ( languages.indexOf( language ) === -1 ) { // languages.push( language ); // } // labelsEditor.dataAliases[language] = $.map( langAliases, function( // langAlias ) { // return langAlias.value; // } ); // } ); // } this.oldLabels = $.extend( {}, this.dataLabels ); this.oldDescriptions = $.extend( {}, this.dataDescriptions ); languages.sort(); var contentLang = mw.config.get( 'wgContentLanguage' ); var userLang = mw.config.get( 'wgUserLanguage' ); languages = $.grep( languages, function( item ) { return item !== contentLang && item !== userLang; } ); languages.splice( 0, 0, contentLang ); if ( contentLang !== userLang ) { languages.splice( 0, 0, userLang ); } $.each( languages, function( i, language ) { $( document.createElement( 'option' ) ).attr( 'value', language ).text( language ).appendTo( labelsEditor.langSelect ); } ); this.currentLanguage = null; if ( WEF_Utils.isWikidata() ) { this.langSelect.val( userLang ); } else { this.langSelect.val( contentLang ); } this.switchLanguage(); }; WEF_LabelsEditor.prototype.switchLanguage = function() { "use strict"; var selectedLanguage = this.langSelect.val(); if ( selectedLanguage == this.currentLanguage ) { return; } this._storeCurrentData(); this.currentLanguage = selectedLanguage; if ( this.dataLabels[this.currentLanguage] !== 'undefined' ) { this.inputLabel.val( this.dataLabels[this.currentLanguage] ); } else { this.inputLabel.val( '' ); } if ( this.dataDescriptions[this.currentLanguage] !== 'undefined' ) { this.inputDescription.val( this.dataDescriptions[this.currentLanguage] ); } else { this.inputDescription.val( '' ); } }; WEF_LabelsEditor.prototype._storeCurrentData = function() { "use strict"; if ( this.currentLanguage !== null ) { this.dataLabels[this.currentLanguage] = ( "" + this.inputLabel.val() ).trim(); this.dataDescriptions[this.currentLanguage] = ( "" + this.inputDescription.val() ).trim(); } }; /** * @param {WEF_Updates} * updates */ WEF_LabelsEditor.prototype.collectUpdates = function( updates ) { "use strict"; var labelsEditor = this; this._storeCurrentData(); $.each( this.dataLabels, function( language, label ) { if ( !WEF_Utils.isEmpty( label ) ) { if ( labelsEditor.oldLabels[language] !== label ) { updates.setLabel( language, label ); } } } ); $.each( this.dataDescriptions, function( language, description ) { if ( !WEF_Utils.isEmpty( description ) ) { if ( labelsEditor.oldDescriptions[language] !== description ) { updates.setDescription( language, description ); } } } ); }; /** * Creates editor from definition. Definition includes: * <ul> * <li><tt>code</tt> -- expression like <tt>P123</tt> to edit property * value or expression like * <tt>P234[Q456]/P567<tt> to edit qualifier value under specified property with specified value * <li><tt>datatype</tt> -- property datatype. Currently supported: * <ul> * <li><tt>string</tt> * <li><tt>url</tt> * <li><tt>wikibase-item</tt> * </ul> * <li><tt>flag</tt> -- Flag code to show before label * <li><tt>label</tt> -- Wikidata code to load label from * <li><tt>labelPrefix</tt> -- Text to add to label (no i18n) * <li><tt>labelQualifier</tt> -- An array of Wikidata items to additionally qualify property label * <li><tt>qualifiers</tt> -- An array of Wikidata property ID that will be added to qualifiers list by default * <li><tt>check</tt> -- function to check value correctness * <li><tt>normalize</tt> -- function to normalize value (including loaded one) * </ul> * The following events (using JQuery wrapper) are supported: * <ul> * <li><tt>change</tt> * </ul> * * On exit there is an editor structure: * <ul> * <li><tt>tbody</tt> -- jQuery HTML TBODY element of editor * <li><tt>collectUpdates( updates )</tt> -- updates special structure: * <ul> * <li><tt>data</tt> -- JSON structure to be sent to <tt>wgeditclaims</tt> to update Wikidata claim * <li><tt>removedClaims</tt> -- list of claims ID to be removed * </ul> * <li><tt>hide( )</tt> -- method to hide editor * <li><tt>show( )</tt> -- method to show editor * <li><tt>hideLabel( placeholderText )</tt> -- hide label (optionally replace with placeholder) * <li><tt>showLabel( )</tt> -- show original label * <li><tt>load( value )</tt> -- load stored value into editor. The whole claim shall be loaded * <li><tt>getDataValue( )</tt> -- return current value JSON * <li><tt>setDataValue( value )</tt> -- updates current value JSON * </ul> * @param definition {WEP_Definition} property definition * @class */ var WEF_ClaimEditor = function( definition ) { this.definition = definition; var i18n = wef_Editors_i18n; var claimEditor = this; /** @type WEF_ClaimReferencesEditor */ this.referencesEditor = null; this.isPropertyEditor = /^P\d+$/i.test( definition.code ); this.isQualifierEditor = /^P\d+\[Q\d+\]\/P\d+$/i.test( definition.code ); /** * Main property ID * * @type {string} */ this.propertyId; /** * Required property value * * @type {string} */ this.propertyValue; /** * Qualifier property to edit * * @type {string} */ this.qualifierPropertyId; if ( this.isPropertyEditor ) { var test = definition.code.match( /^P(\d+)$/i ); this.propertyId = 'P' + test[1]; this.propertyValue = undefined; this.qualifierPropertyId = undefined; } else if ( this.isQualifierEditor ) { var test = definition.code.match( /^P(\d+)\[Q(\d+)\]\/P(\d+)$/i ); this.propertyId = 'P' + test[1]; this.propertyValue = 'Q' + test[2]; this.qualifierPropertyId = 'P' + test[3]; } else { throw new Error( 'Unsupported code: ' + definition.code ); } this.tbody = $( document.createElement( 'tbody' ) ).addClass( 'wef_property_editor_tbody' ).addClass( 'wef_property_editor_' + this.propertyId ); var row1 = this.row1 = $( document.createElement( 'tr' ) ).addClass( 'wef_property_editor_row' ).appendTo( this.tbody ); var rankCell = $( document.createElement( 'td' ) ).addClass( 'wef_property_editor_rank wef_button_cell' ).appendTo( row1 ); var flagCell = $( document.createElement( 'td' ) ).addClass( 'wef_property_editor_flag' ).appendTo( row1 ); var labelCell = $( document.createElement( 'th' ) ).addClass( 'wef_property_editor_label' ).appendTo( row1 ); var beforeInputCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( row1 ); var inputCell = $( document.createElement( 'td' ) ).addClass( 'wef_property_editor_input' ).appendTo( row1 ); var sourcesButtonCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( row1 ); var columnTables = this._columnTables = {}; if ( !WEF_Utils.isEmpty( definition.columns ) ) { $.each( definition.columns, function( i, columnDefinition ) { if ( !WEF_Utils.isEmpty( columnDefinition.code ) ) { var addColumnQualifierCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).addClass( 'wef_button_cell_addColumnQualifier' ).appendTo( row1 ); $( document.createElement( 'button' ) ).attr( 'type', 'button' ).button( { icons: { primary: 'ui-icon-plus' }, text: false, label: i18n.buttonAddQualifier, } ).click( function() { var qualifierEditor = claimEditor.addQualifier( columnDefinition.code ); qualifierEditor.initWithEmpty( columnDefinition.code, columnDefinition.datatype, columnDefinition.editordatatype ); } ).addClass( 'wef_property_button' ).appendTo( addColumnQualifierCell ); var columnCell = $( document.createElement( 'td' ) ).addClass( 'wef_property_editor_column_cell' ).appendTo( row1 ); wef_LabelsCache.getOrQueue( columnDefinition.code, function( label, description ) { columnCell.attr( 'title', description ); } ); var columnTable = $( document.createElement( 'table' ) ).addClass( 'wef_property_editor_column_table' ).appendTo( columnCell ); columnTables[columnDefinition.code] = columnTable; } } ); } if ( this.isPropertyEditor ) { wef_LabelsCache.getOrQueue( this.propertyId, function( label, description ) { if ( !WEF_Utils.isEmpty( description ) && description !== this.propertyId ) row1.attr( 'title', description ); } ); } this.snakEditor = new WEF_SnakEditor( inputCell, definition ); /* Rank */ this.rankButton = $( document.createElement( 'button' ) ).attr( 'type', 'button' ).addClass( 'wef_property_button' ).addClass( 'wef_button_rank_normal' ).button( { icons: { primary: 'ui-icon-arrowthick-2-n-s' }, text: false, label: i18n.rankNormalValue, } ).appendTo( rankCell ); this.rankButton.click( function() { if ( wef_selectRank.visible && wef_selectRank.initiator === this ) { wef_selectRank.hide(); } else { wef_selectRank.initiator = this; wef_selectRank.show( claimEditor.rankButton, claimEditor.rank, function( value ) { claimEditor.setRank( value ); } ); } } ); /* Flag */ if ( definition.flag !== 'undefined' && typeof ruWikiFlagsHtml !== 'undefined' && typeof ruWikiFlagsHtml[definition.flag] !== 'undefined' ) { flagCell.html( ruWikiFlagsHtml[definition.flag] ); } /* Label */ this._labelToDisplay = WEF_ClaimEditor._getLabel( definition ); this._labelPlaceholder = $( document.createElement( 'label' ) ); labelCell.empty(); labelCell.append( this._labelToDisplay ); labelCell.append( this._labelPlaceholder ); /* Sources */ this.sourcesButton = $( document.createElement( 'button' ) ).attr( 'type', 'button' ).addClass( 'wef_property_button' ).addClass( 'wef_button_sources' ).button( { text: true, label: '[0]', } ).appendTo( sourcesButtonCell ); this.sourcesButton.click( function() { if ( claimEditor.referencesEditor == null ) { claimEditor.referencesEditor = new WEF_ClaimReferencesEditor( parent ); claimEditor.referencesEditor.load( claimEditor.references ); } claimEditor.referencesEditor.show(); } ); var row2 = $( document.createElement( 'tr' ) ).addClass( 'wef_property_editor_row' ).appendTo( this.tbody ); $( document.createElement( 'td' ) ).addClass( 'wef_property_editor_cell_emtpy' ).appendTo( row2 ); var bottomContentCell = $( document.createElement( 'td' ) ).addClass( 'wef_property_editor_bottom_content' ).attr( 'colspan', '100' ).appendTo( row2 ); this._bottomContentTable = $( document.createElement( 'table' ) ).addClass( 'wef_qualifiers' ).appendTo( bottomContentCell ); this.disabled = false; /** @type {WEF_Definition} */ this.definition = definition; this.wikidataClaim = null; this.wikidataSnak = null; this.wikidataOldValue = null; this.rank = WEF_RANK_NORMAL; this.references = null; $( this.snakEditor ).change( function() { $( claimEditor ).change(); } ); /* Qualifiers support */ /** @type {WEF_QualifierEditor[]} */ this.qualifiers = []; /** @type {string[]} */ this.removedQualifiersHashes = []; /* Add qualifier button */ if ( typeof definition.qualifiers !== 'undefined' && definition.qualifiers.length > 0 ) { $( document.createElement( 'button' ) ).attr( 'type', 'button' ).addClass( 'wef_property_button' ).button( { icons: { primary: 'ui-icon-tag' }, text: false, label: i18n.buttonAddQualifier, } ).click( function() { claimEditor.addQualifier(); } ).appendTo( beforeInputCell ); } }; WEF_ClaimEditor._getLabel = function( definition ) { var label = $( document.createElement( 'label' ) ); var updateLabel = function() { var newLabel = ''; if ( typeof definition.labelPrefix !== 'undefined' ) { newLabel += definition.labelPrefix; } if ( typeof definition.label !== 'undefined' ) { newLabel += wef_LabelsCache.getLabel( definition.label ); } if ( typeof definition.labelQualifier !== 'undefined' ) { if ( $.isArray( definition.labelQualifier ) ) { newLabel += ' ('; $.each( definition.labelQualifier, function( index, qualifier ) { if ( index !== 0 ) { newLabel += ', '; } newLabel += wef_LabelsCache.getLabel( qualifier ); } ); newLabel += ')'; } else { newLabel += ' (' + wef_LabelsCache.getLabel( definition.labelQualifier ) + ')'; } } label.text( newLabel ); label.attr( 'title', wef_LabelsCache.getDescription( definition.label ) ); }; if ( typeof definition.label !== 'undefined' ) { wef_LabelsCache.getOrQueue( definition.label, updateLabel ); } if ( typeof definition.labelQualifier !== 'undefined' ) { if ( $.isArray( definition.labelQualifier ) ) { $.each( definition.labelQualifier, function( index, qualifier ) { wef_LabelsCache.getOrQueue( qualifier, updateLabel ); } ); } else { wef_LabelsCache.getOrQueue( definition.labelQualifier, updateLabel ); } } updateLabel(); return label; }; WEF_ClaimEditor.prototype.hideLabel = function( placeholderText ) { if ( typeof placeholderText === 'string' ) { this._labelPlaceholder.text( placeholderText ); } this._labelToDisplay.hide(); this._labelPlaceholder.show(); }; WEF_ClaimEditor.prototype.showLabel = function() { this._labelToDisplay.show(); this._labelPlaceholder.hide(); }; WEF_ClaimEditor.prototype.hasData = function() { return this.snakEditor.hasData(); }; WEF_ClaimEditor.prototype.hasValue = function() { return this.snakEditor.hasValue(); }; WEF_ClaimEditor.prototype.remove = function() { this.tbody.remove(); }; WEF_ClaimEditor.prototype.getDataValue = function() { return this.snakEditor.getDataValue(); }; WEF_ClaimEditor.prototype.getSnakValue = function() { if ( !this.hasData() ) { throw new Error( 'no data' ); } var snak = {}; snak.snaktype = this.snakEditor.snakTypeMode; if ( this.isPropertyEditor ) { snak.property = this.propertyId; } if ( this.isQualifierEditor ) { snak.property = this.qualifierPropertyId; if ( this.wikidataSnak !== null ) { snak.hash = this.wikidataSnak.hash; } } snak.datatype = this.definition.datatype; if ( this.snakEditor.snakTypeMode === 'value' ) { snak.datavalue = this.getDataValue(); } return snak; }; WEF_ClaimEditor.prototype.initEmpty = function() { // we have definition only this.rank = WEF_RANK_NORMAL; this.snakEditor.initEmptyWithDataType( this.isPropertyEditor ? this.propertyId : this.qualifierPropertyId, this.definition.datatype ); this.references = []; this.wikidataClaim = null; this.wikidataOldValue = null; this.wikidataOldReferences = null; }; WEF_ClaimEditor.prototype.initWithValue = function( claim ) { this.wikidataClaim = claim; if ( typeof claim.rank === 'undefined' ) { this.setRank( WEF_RANK_NORMAL ); } else { this.setRank( claim.rank ); } this.references = typeof claim.references !== 'undefined' && claim.references !== null ? claim.references : []; this.sourcesButton.button( "option", "label", "[" + this.references.length + "]" ); if ( this.isPropertyEditor ) { // load property main snak this.wikidataSnak = claim.mainsnak; if ( claim.mainsnak ) { this.snakEditor.initWithValue( claim.mainsnak ); } else { // WTF? this.snakEditor.initEmptyWithDataType( this.propertyId, definition.datatype ); } } else if ( this.isQualifierEditor ) { /* * since it's loading time, we assume there is qualifier with specified * value */ var qualifiers = claim.qualifiers[this.qualifierPropertyId]; if ( !$.isArray( qualifiers ) ) { throw new Error( 'Qualifiers «' + this.qualifierPropertyId + '» of ' + this.propertyId + '[' + this.propertyValue + '] not found or not an array' ); } if ( qualifiers.length != 1 ) { throw new Error( 'Length of qualifiers «' + this.qualifierPropertyId + '» of ' + this.propertyId + '[' + this.propertyValue + '] is not 1 as expected' ); } var qualifier = qualifiers[0]; this.wikidataSnak = qualifier; this.snakEditor.initWithValue( qualifier ); } else { throw new Error( 'Unsupported code: ' + definition.code ); } /* * Remember the values to compare them later with future ones to check if * update in Wikidata required */ this.wikidataOldRank = this.rank; this.wikidataOldValue = this.hasData() ? JSON.stringify( this.getSnakValue() ) : null; this.wikidataOldReferences = JSON.stringify( this.references ); var claimEditor = this; if ( typeof claim.qualifiers !== 'undefined' ) { $.each( claim.qualifiers, function( property, qualifiers ) { if ( claimEditor.isQualifierEditor && property === claimEditor.qualifierPropertyId ) { return; } $.each( qualifiers, function( index, qualifier ) { var qualifierEditor = claimEditor.addQualifier( qualifier.property ); qualifierEditor.initWithValue( qualifier ); } ); } ); } }; WEF_ClaimEditor.prototype.initWithStringValue = function( strValue ) { this.rank = WEF_RANK_NORMAL; this.references = []; this.sourcesButton.button( "option", "label", "[0]" ); this.wikidataClaim = null; this.wikidataOldValue = null; this.wikidataOldReferences = null; this.snakEditor.initWithValue( { snaktype: 'value', property: this.isPropertyEditor ? this.propertyId : this.qualifierPropertyId, datatype: 'string', datavalue: { value: strValue, type: 'string' } } ); }; WEF_ClaimEditor.prototype.setDataValue = function( newDataValue ) { this.snakEditor.setDataValue( newDataValue ); }; WEF_ClaimEditor.prototype.setRank = function( newRank ) { this.rank = newRank; switch ( newRank ) { case WEF_RANK_PREFERRED: this.rankButton.button( 'option', 'label', wef_Editors_i18n.rankPreferredValue ); this.rankButton.button( 'option', 'icons', { primary: 'ui-icon-arrowthickstop-1-n' } ); break; case WEF_RANK_NORMAL: this.rankButton.button( 'option', 'label', wef_Editors_i18n.rankNormalValue ); this.rankButton.button( 'option', 'icons', { primary: 'ui-icon-arrowthick-2-n-s' } ); break; case WEF_RANK_DEPRECATED: this.rankButton.button( 'option', 'label', wef_Editors_i18n.rankDeprecatedValue ); this.rankButton.button( 'option', 'icons', { primary: 'ui-icon-arrowthickstop-1-s' } ); break; } }; WEF_ClaimEditor.prototype.setStringValue = function( strValue ) { this.snakEditor.setSnakValue( { snaktype: 'value', property: this.isPropertyEditor ? this.propertyId : this.qualifierPropertyId, datatype: 'string', datavalue: { value: strValue, type: 'string' } } ); }; /** * @param updates * {WEF_Updates} */ WEF_ClaimEditor.prototype.collectUpdates = function( updates ) { if ( this.disabled === true ) { return; } // check if we have any changes var hasData = this.snakEditor.hasData(); var newSnak = hasData ? this.getSnakValue() : null; var oldClaim = this.wikidataClaim; var oldSnak = this.wikidataSnak; var oldSnakStr = this.wikidataOldValue; var oldRank = this.wikidataOldRank; var oldReferencesStr = this.wikidataOldReferences; if ( hasData === false ) { if ( oldClaim !== null ) { updates.removedClaims.push( oldClaim.id ); } } else { var claim = {}; if ( oldClaim !== null ) { $.extend( claim, oldClaim ); // qualifiers we will refill by ourselfs delete claim.qualifiers; delete claim['qualifiers-order']; delete claim.rank; delete claim.references; } else { claim.type = 'statement'; } claim.rank = this.rank; if ( this.referencesEditor !== null ) { this.references = this.referencesEditor.collect(); } claim.references = this.references; if ( this.isPropertyEditor === true ) { claim.mainsnak = newSnak; } else if ( this.isQualifierEditor === true ) { if ( oldClaim === null ) { claim.mainsnak = WEF_Utils.newWikibaseItemSnak( this.propertyId, 'item', Number( this.propertyValue.substr( 1 ) ) ); } var qualifier = newSnak; if ( oldSnak !== null ) { qualifier.hash = oldSnak.hash; } WEF_Utils.appendToNamedMap( claim, 'qualifiers', this.qualifierPropertyId, qualifier ); } else { throw new Error( 'Unsupported code: ' + definition.code ); } var needToUpdateClaim = this.rank !== oldRank || JSON.stringify( newSnak ) !== oldSnakStr || JSON.stringify( this.references ) !== oldReferencesStr; // save qualifiers $.each( this.qualifiers, function( index, qualifierEditor ) { needToUpdateClaim = qualifierEditor.collectUpdates( claim ) || needToUpdateClaim; } ); needToUpdateClaim = needToUpdateClaim || ( this.removedQualifiersHashes.length > 0 ); if ( needToUpdateClaim === true ) { WEF_Utils.appendToNamedMap( updates.data, 'claims', this.propertyId, claim ); } } }; WEF_ClaimEditor.prototype.addQualifier = function( qualifierId ) { var claimEditor = this; if ( WEF_Utils.isEmpty( qualifierId ) || typeof this._columnTables[qualifierId] === 'undefined' ) { var qualifierEditor = new WEF_SelectableQualifierEditor( this._bottomContentTable, this.definition.qualifiers, function( removedQualifierEditor ) { var hash = removedQualifierEditor.getHash(); if ( hash !== null ) { claimEditor.removedQualifiersHashes.push( hash ); } } ); this.qualifiers.push( qualifierEditor ); return qualifierEditor; } var targetCell = this._columnTables[qualifierId]; var qualifierEditor = new WEF_QualifierEditor( targetCell, qualifierId, function( removedQualifierEditor ) { var hash = removedQualifierEditor.getHash(); if ( hash !== null ) { claimEditor.removedQualifiersHashes.push( hash ); } } ); this.qualifiers.push( qualifierEditor ); return qualifierEditor; }; /** * Organize multiple claim edit rows into single structure * * @param {WEF_Definition} * definition * @class */ WEF_ClaimEditorsTable = function( definition ) { this.definition = definition; var propertyEditorsTable = this; var i18n = wef_Editors_i18n; /** @type {WEF_ClaimEditor[]} */ var claimEditors = []; /** @type {string[]} */ var removedClaims = []; var placed = false; var temporaryHolder = null; var changeF = function() { $( propertyEditorsTable ).change(); }; /** @returns {WEF_ClaimEditor} */ this.add = function() { if ( placed === false ) { throw new Error( 'Claims edit table is not placed on the form yet' ); } var claimEditor = new WEF_ClaimEditor( definition ); var buttonAddClaim = $( document.createElement( 'button' ) ).attr( 'type', 'button' ).addClass( 'wef_property_button' ).button( { icons: { primary: 'ui-icon-plus' }, text: false, label: i18n.buttonAddClaim, } ).click( function() { var editor = propertyEditorsTable.add(); editor.initEmpty(); } ); var buttonRemoveClaim = $( document.createElement( 'button' ) ).attr( 'type', 'button' ).addClass( 'wef_property_button' ).button( { icons: { primary: 'ui-icon-trash' }, text: false, label: i18n.buttonRemoveClaim, } ).click( function() { var question = i18n.confirmDeleteClaim // .replace( '{code}', definition.label ) // .replace( '{label}', wef_LabelsCache.getLabel( definition.label ) ); var r = !claimEditor.hasData() || confirm( question ); if ( r === true ) { /* * add before removing to insert immediately after last existing */ if ( claimEditors.length === 1 ) { var editor = propertyEditorsTable.add(); editor.initEmpty(); } claimEditors = jQuery.grep( claimEditors, function( value ) { return value != claimEditor; } ); if ( claimEditor.wikidataClaim != null && !WEF_Utils.isEmpty( claimEditor.wikidataClaim.id ) ) { removedClaims.push( claimEditor.wikidataClaim.id ); } claimEditor.remove(); } } ); /** @type {function} */ var normalizeF = definition.normalize; /** @type {function} */ var urlF = definition.url; // append before URL and after input cell var buttonsCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( claimEditor.row1 ); { try { if ( definition.datatype === 'url' ) { var newButton = $( document.createElement( 'button' ) ).addClass( 'wef_property_button' ).attr( 'type', 'button' ); newButton.button( { icons: { primary: 'ui-icon-extlink' }, disabled: true, text: false, label: i18n.buttonUrlNavigate, } ).click( function() { if ( claimEditor.hasValue() ) { window.open( claimEditor.getDataValue().value, '_blank' ); } } ); $( claimEditor ).change( function() { if ( claimEditor.hasValue() ) { newButton.button( 'option', 'disabled', false ); newButton.button( 'enable' ); } else { newButton.button( 'option', 'disabled', true ); newButton.button( 'disable' ); } } ); buttonsCell.append( newButton ); } } catch ( err ) { mw.log.warn( 'Unable to attach URL button: ' + err ); } if ( typeof definition.buttons !== 'undefined' ) { $.each( definition.buttons, function( index, buttonDefinition ) { var newButton = $( document.createElement( 'button' ) ).addClass( 'wef_property_button' ).attr( 'type', 'button' ); newButton.button( buttonDefinition ); if ( $.isFunction( buttonDefinition.click ) ) { newButton.click( function() { buttonDefinition.click( claimEditor ); } ); } if ( $.isFunction( buttonDefinition.init ) ) { buttonDefinition.init( claimEditor ); } buttonsCell.append( newButton ); } ); } } if ( $.isFunction( urlF ) ) { claimEditor.row1.find( 'td.wef_property_editor_input' ).addClass( 'wef_external_links_before_url_cell' ); var urlCell = $( document.createElement( 'td' ) ).addClass( 'wef_external_links_url_cell' ).appendTo( claimEditor.row1 ); var div = $( '<div>&nbsp;</div>' ).addClass( 'wef_external_links_url_div' ).appendTo( urlCell ); var a = $( document.createElement( 'a' ) ).addClass( 'wef_external_links_url_a' ).appendTo( div ).attr( 'target', '_blank' ); var updateLinkImplF = function( newValue ) { if ( $.isFunction( normalizeF ) ) { var newValueNormalized = normalizeF( newValue ); if ( newValue !== newValueNormalized ) { claimEditor.setStringValue( newValueNormalized ); return; } } if ( newValue ) { var newUrl = urlF( newValue ); a.attr( 'href', newUrl ); a.text( newUrl ); // if ( typeof definition.check !== 'undefined' ) { // var result = definition.check.exec( newValue ); // if ( result == null ) { // var tip = i18n.getTip( definition ); // var shortLabel = getLabelTextShort( definition ); // tip = tip.replace( '{0}', shortLabel ); // statusAndTips.text( tip ); // statusAndTips.addClass( 'ui-state-error' ); // } else { // statusAndTips.text( '' ); // statusAndTips.removeClass( 'ui-state-error' ); // } // } } else { a.attr( 'href', '' ); a.text( '' ); // statusAndTips.text( '' ); // statusAndTips.removeClass( 'ui-state-error' ); } }; var updateLinkF = function() { if ( claimEditor.hasValue() ) { updateLinkImplF( claimEditor.getDataValue().value ); } else { updateLinkImplF( '' ); } }; $( claimEditor ).change( updateLinkF ); // additional placeholders to align buttons after URL fields $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( claimEditor.row1 ); $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( claimEditor.row1 ); } else { claimEditor.row1.find( 'td.wef_property_editor_input' ).attr( 'colspan', 4 ); } var beforeCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).prependTo( claimEditor.row1 ); beforeCell.append( buttonAddClaim ); var afterCell = $( document.createElement( 'td' ) ).addClass( 'wef_button_cell' ).appendTo( claimEditor.row1 ); afterCell.append( buttonRemoveClaim ); claimEditors.push( claimEditor ); if ( temporaryHolder !== null ) { claimEditor.tbody.replaceAll( temporaryHolder ); temporaryHolder = null; } else { var prev = claimEditors[claimEditors.length - 2].tbody; var curr = claimEditors[claimEditors.length - 1].tbody; curr.insertAfter( prev ); } $( claimEditor ).change( function() { changeF(); } ); return claimEditor; }; /** * Init editor with values. Must be called after placement on the form. * * @param entity * {WEF_Entity} */ this.init = function( entity ) { if ( placed === false ) { throw new Error( 'Claims edit table is not placed on the form yet' ); } /** @type {WEF_Claim[]} */ var claims = WEF_filterClaims( definition, entity.claims ); $.each( claims, function( i, claim ) { /** @type {WEF_ClaimEditor} */ var editor = propertyEditorsTable.add(); editor.initWithValue( claim ); } ); if ( this.size() === 0 ) { /** @type {WEF_ClaimEditor} */ var editor = this.add(); editor.initEmpty(); } }; /** * Init editor with values. Must be called after placement on the form. * * @param entity * {WEF_Entity} */ this.initAsEmpty = function() { if ( placed === false ) { throw new Error( 'Claims edit table is not placed on the form yet' ); } /** @type {WEF_ClaimEditor} */ var editor = this.add(); editor.initEmpty(); }; function createPlaceholder( target ) { if ( WEF_Utils.isEmpty( definition.columns ) ) { temporaryHolder = $( document.createElement( 'tbody' ) ).html( '<!-- Temporary holder for ' + definition.code + ' -->' ); return temporaryHolder; } var container = $( document.createElement( 'tbody' ) ); var columnsTable = $( document.createElement( 'table' ) ).addClass( 'wef_columns_table' ).appendTo( container ); var columnsHeader = $( document.createElement( 'tr' ) ).addClass( 'wef_columns_header' ).appendTo( columnsTable ); // empty cell for adding claim button columnsHeader.append( $( document.createElement( 'th' ) ).addClass( 'wef_column_th_empty' ) ); var propertyName = $( document.createElement( 'th' ) ).addClass( 'wef_column_th' ).attr( 'colspan', '8' ).appendTo( columnsHeader ); if ( typeof definition.label !== 'undefined' ) { wef_LabelsCache.getOrQueue( definition.label, function( label, description ) { propertyName.text( label ); propertyName.attr( 'title', description ); } ); } $.each( definition.columns, function( i, columnDefinition ) { if ( !WEF_Utils.isEmpty( columnDefinition.code ) ) { var columnName = $( document.createElement( 'th' ) ).addClass( 'wef_column_th' ).attr( 'colspan', '2' ).appendTo( columnsHeader ); if ( typeof columnDefinition.label !== 'undefined' ) { wef_LabelsCache.getOrQueue( columnDefinition.label, function( label, description ) { columnName.text( label ); columnName.attr( 'title', description ); } ); } } } ); temporaryHolder = $( document.createElement( 'tbody' ) ).html( '<!-- Temporary holder for ' + definition.code + ' -->' ); temporaryHolder.appendTo( columnsTable ); return container; } this.appendTo = function( target ) { if ( placed === true ) { throw new Error( 'Claims edit table is already placed on the form' ); } placed = true; createPlaceholder().appendTo( target ); return; }; /** Replace each target element with the set of matched elements. */ this.replaceAll = function( target ) { if ( placed === true ) { throw new Error( 'Claims edit table is already placed on the form' ); } placed = true; createPlaceholder().replaceAll( target ); return; }; /** * @param {WEF_Updates} * updates */ this.collectUpdates = function( updates ) { $.each( claimEditors, function( i, claimEditor ) { claimEditor.collectUpdates( updates ); } ); for ( var index = 0; index < removedClaims.length; index++ ) { updates.removedClaims.push( removedClaims[index] ); } }; /** * Looking for equals value and mark it as foung (light-green) or create new * item and mark it as new */ this.onFoundValue = function( strValue ) { function hasStringValue( claimEditor, lookupValue ) { if ( !claimEditor.hasValue() ) { return false; } var dataValue = claimEditor.getDataValue(); return typeof dataValue === 'object' && dataValue.type === 'string' && typeof dataValue.value === 'string' && dataValue.value === lookupValue; } var found = false; $.each( claimEditors, function( i, claimEditor ) { if ( hasStringValue( claimEditor, strValue ) ) { claimEditor.tbody.addClass( 'wef-lookup-found' ); found = true; } } ); if ( found === false ) { var withEmpty = $.grep( claimEditors, function( claimEditor ) { return !claimEditor.hasValue(); } ); if ( withEmpty.length === 0 ) { var newClaimEditor = this.add(); newClaimEditor.initWithStringValue( strValue ); newClaimEditor.tbody.addClass( 'wef-lookup-found-new' ); } else { var newClaimEditor = withEmpty[0]; newClaimEditor.setStringValue( strValue ); newClaimEditor.tbody.addClass( 'wef-lookup-found-new' ); } } }; /** * @returns {number} the number of values, including no-value and some-value * snaks */ this.getHasDataSize = function() { var counter = 0; $.each( claimEditors, function( index, claimEditor ) { if ( claimEditor.hasData() ) { counter++; } } ); return counter; }; this.size = function() { return claimEditors.length; }; }; window.WEF_ClaimEditorsTable = WEF_ClaimEditorsTable; WEF_ClaimEditorsTable.removeFoundValueClasses = function() { $( '.wef-lookup-found' ).removeClass( 'wef-lookup-found' ); $( '.wef-lookup-found-new' ).removeClass( 'wef-lookup-found-new' ); }; WEF_ProgressItem = function( parentUl, text ) { this._span1 = $( document.createElement( 'span' ) ); this._span2 = $( document.createElement( 'span' ) ).text( text ); this._li = $( document.createElement( 'li' ) ).addClass( 'wef_progress_item' ).append( this._span1 ).append( '&nbsp;' ).append( this._span2 ).appendTo( parentUl ); }; WEF_ProgressItem.prototype.inProgress = function() { this._span1.html( wef_Editors_i18n.htmlInProgress ); }; WEF_ProgressItem.prototype.success = function() { this._span1.html( wef_Editors_i18n.htmlSuccess ); }; WEF_ProgressItem.prototype.failure = function( failureReason ) { this._span1.html( wef_Editors_i18n.htmlFailure ); if ( failureReason ) { this._span2.append( ': ' + failureReason ); } }; WEF_ProgressItem.prototype.notNeeded = function() { this._span1.html( wef_Editors_i18n.htmlNotNeeded ); }; /** * @param {string} * entityId * @class */ var WEF_Updates = function( entityId ) { /** {string} */ this.entityId = entityId; this.data = {}; this.removedClaims = []; }; WEF_Updates.prototype.setLabel = function( language, value ) { "use strict"; if ( typeof this.data.labels === 'undefined' ) { this.data.labels = {}; } this.data.labels[language] = { language: language, value: value }; }; WEF_Updates.prototype.setDescription = function( language, value ) { "use strict"; if ( typeof this.data.descriptions === 'undefined' ) { this.data.descriptions = {}; } this.data.descriptions[language] = { language: language, value: value }; }; WEF_Updates.prototype.setSitelink = function( site, title ) { "use strict"; if ( typeof this.data.sitelinks === 'undefined' ) { this.data.sitelinks = {}; } this.data.sitelinks[site] = { site: site, title: title }; }; window.WEF_Updates = WEF_Updates; /** * @param {boolean} * currentPageItem * @param {String} * entityId * @param {WEF_LabelsEditor} * labelsEditor * @param {WEF_ClaimEditorsTable[]} * claimEditorTables */ window.wef_analyze_and_save = function( currentPageItem, entityId, labelsEditor, claimEditorTables ) { var i18n = wef_Editors_i18n; var d = $.Deferred(); var dialog = $( document.createElement( 'div' ) ); dialog.attr( 'title', i18n.dialogAnalyzeChangesTitle ); var analyzeProgressUl = $( document.createElement( 'ul' ) ).appendTo( dialog ); var analyzeProgress = new WEF_ProgressItem( analyzeProgressUl, i18n.actionAnalyzeChanges ); analyzeProgress.inProgress(); dialog.dialog( { height: 'auto', width: 'auto' } ); var updates = new WEF_Updates( entityId ); try { if ( currentPageItem && WEF_Utils.isEmpty( entityId ) && !WEF_Utils.isWikidata() ) { // set label in current content language updates.setLabel( mw.config.get( 'wgContentLanguage' ), mw.config.get( 'wgPageName' ) ); // TODO: check documentation about using wgDBname // attach current site updates.setSitelink( mw.config.get( 'wgDBname' ), mw.config.get( 'wgPageName' ) ); } if ( labelsEditor != null ) { labelsEditor.collectUpdates( updates ); } $.each( claimEditorTables, function( i, claimEditorTable ) { claimEditorTable.collectUpdates( updates ); } ); if ( $.isEmptyObject( updates.data ) && updates.removedClaims.length === 0 ) { var purgeProgress = new WEF_ProgressItem( analyzeProgressUl, i18n.actionNoChangesPurge ); analyzeProgress.success(); purgeProgress.inProgress(); d.resolve( updates.entityId ); dialog.dialog( 'close' ); return d; } analyzeProgress.success(); } catch ( error ) { mw.log.warn( i18n.errorAnalyzeChanges + ': ' + error ); analyzeProgress.failure( '' + error ); alert( i18n.errorAnalyzeChanges + ': ' + error ); d.reject( error ); return d; } dialog.dialog( 'close' ); var d2 = WEF_Utils.update( updates ); d2.done( function() { d.resolve( updates.entityId ); } ); d2.fail( function( arg ) { d.reject( arg ); } ); return d; }; WEF_EditorForm = function( originalTitle, html, i18n, currentPageItem, editDeferred ) { this.currentPageItem = currentPageItem; this.editDeferred = editDeferred; var editorForm = this; /** @type {WEF_LabelsEditor} */ var labelsEditor = null; /** @type {WEF_ClaimEditorsTable[]} */ var claimEditorsTables = []; var dialog = $( html ); /** * @type {string} * @const */ var DATAKEY_ANCHOR_EDITOR_TABLES = 'wef-achor-editors'; var DATAKEY_ANCHOR_ORIGINAL_TEXT = 'wef-original-text'; var enableAnchorCounterUpdate = false; dialog.find( '.wef_i18n_text' ).each( function( i, htmlItem ) { try { var item = $( htmlItem ); var code = item.text(); var translated = i18n[code]; if ( typeof translated !== 'undefined' ) { item.text( translated ); item.removeClass( 'wef_i18n_text' ); } } catch ( err ) { mw.log.warn( 'Unable to translate element text: ' + err ); } } ); dialog.find( '.wef_i18n_label' ).each( function( i, htmlItem ) { try { var item = $( htmlItem ); var code = item.text(); wef_LabelsCache.getOrQueue( code, function( label, description ) { if ( !WEF_Utils.isEmpty( label ) ) { item.text( label ); } if ( !WEF_Utils.isEmpty( description ) ) { item.attr( 'title', description ); } item.removeClass( 'wef_i18n_label' ); if ( item.hasClass( 'wef_editor_tab_anchor' ) ) { item.data( DATAKEY_ANCHOR_ORIGINAL_TEXT, label ); updateAnchorCounter( item ); } } ); } catch ( err ) { mw.log.warn( 'Unable to translate element text: ' + err ); } } ); function updateLinkedAnchorCounter() { if ( enableAnchorCounterUpdate === false ) return; try { /** @type {WEF_ClaimEditorsTable} */ var currentClaimEditorTable = this; if ( typeof currentClaimEditorTable.wefTabAnchor === 'undefined' ) { return; } var anchor = currentClaimEditorTable.wefTabAnchor; updateAnchorCounter( anchor ); } catch ( err ) { mw.log.warn( 'Unable to update editors count on tab: ' + err ); } } function updateAnchorCounter( anchor ) { if ( enableAnchorCounterUpdate === false ) return; try { var claimEditorTables = anchor.data( DATAKEY_ANCHOR_EDITOR_TABLES ); if ( typeof claimEditorTables === 'undefined' ) { return; } var counter = 0; $.each( claimEditorTables, function( index, claimEditorTable ) { counter += claimEditorTable.getHasDataSize(); } ); var newText = anchor.data( DATAKEY_ANCHOR_ORIGINAL_TEXT ) + ' (' + counter + ')'; anchor.text( newText ); } catch ( err ) { mw.log.warn( 'Unable to update editors count on tab: ' + err ); } } dialog.find( '.wef_editor_tab_anchor' ).each( function( i, anchor ) { var jAnchor = $( anchor ); jAnchor.data( DATAKEY_ANCHOR_ORIGINAL_TEXT, jAnchor.text() ); } ); dialog.find( '.wef_labels_editor' ).each( function( i, htmlItem ) { var item = $( htmlItem ); labelsEditor = new WEF_LabelsEditor(); labelsEditor.replaceAll( item ); } ); dialog.find( '.wef_claim_editors' ).each( function( i, htmlItem ) { var item = $( htmlItem ); var check = WEF_Utils.isEmpty( item.data( 'check' ) ) ? undefined : new RegExp( item.data( 'check' ) ); var code = item.data( 'code' ); var datatype = item.data( 'datatype' ); var flag = item.data( 'flag' ); var label = item.data( 'label' ); var template = WEF_Utils.isEmpty( item.data( 'template' ) ) ? undefined : item.data( 'template' ); if ( typeof label === 'undefined' ) { label = code; } var definition = new WEF_Definition( { check: check, code: code, datatype: datatype, flag: flag, label: label, columns: [], qualifiers: [], template: template, } ); item.find( 'tr' ).each( function( k, qItem ) { var qualifier = $( qItem ); var qDefinition = new WEF_Definition( { code: qualifier.data( 'code' ), editordatatype: qualifier.data( 'editordatatype' ), datatype: qualifier.data( 'datatype' ), label: qualifier.data( 'label' ), } ); if ( WEF_Utils.isEmpty( qDefinition.label ) ) { qDefinition.label = qualifier.data( 'code' ); } if ( qualifier.data( 'as-column' ) === true ) { definition.columns.push( qDefinition ); } else { definition.qualifiers.push( qDefinition ); } } ); WEF_Utils.processDefinition( definition ); var claimEditorTable = new WEF_ClaimEditorsTable( definition ); claimEditorsTables.push( claimEditorTable ); try { // find corresponding anchor to future tab label update var tab = item.parents( '.wef_editor_tab' ); var anchor = dialog.find( 'a.wef_editor_tab_anchor[href="#' + tab.attr( 'id' ) + '"]' ); if ( anchor.length > 0 ) { claimEditorTable.wefTabAnchor = anchor; if ( anchor.data( DATAKEY_ANCHOR_EDITOR_TABLES ) == null ) { anchor.data( DATAKEY_ANCHOR_EDITOR_TABLES, [] ); } anchor.data( DATAKEY_ANCHOR_EDITOR_TABLES ).push( claimEditorTable ); } $( claimEditorTable ).change( updateLinkedAnchorCounter ); } catch ( err ) { mw.log.warn( 'Unable to attach updateAnchorCounter() listener to claimEditorTable: ' + err ); } claimEditorTable.replaceAll( item ); } ); dialog.find( '.wef_tabs' ).tabs(); dialog.dialog( { autoOpen: false, width: 1000, title: originalTitle, buttons: [ { text: i18n.dialogButtonUpdateLabelsText, label: i18n.dialogButtonUpdateLabelsLabel, click: function() { wef_LabelsCache.clearCacheAndRequeue(); wef_LabelsCache.receiveLabels(); }, style: 'position: absolute; left: 1em;', }, { text: i18n.dialogButtonSaveText, label: i18n.dialogButtonSaveLabel, click: function() { dialog.dialog( 'close' ); var saveD = wef_analyze_and_save( editorForm.currentPageItem, editorForm.entityId, labelsEditor, claimEditorsTables ); saveD.done( function( entityId ) { editDeferred.resolve( entityId ); } ); saveD.fail( function() { editDeferred.reject(); } ); }, }, { text: i18n.dialogButtonCancelText, label: i18n.dialogButtonCancelLabel, click: function() { $( this ).dialog( 'close' ); editDeferred.reject(); } } ], } ); this.load = function( entity ) { this.entityId = entity.id.toUpperCase(); wef_LabelsCache.getOrQueue( this.entityId, function( label ) { dialog.dialog( 'option', 'title', '«' + label + '» — ' + originalTitle ); } ); if ( labelsEditor != null ) { labelsEditor.load( entity ); } $.each( claimEditorsTables, function( i, claimEditorsTable ) { claimEditorsTable.init( entity ); } ); enableAnchorCounterUpdate = true; dialog.find( 'a.wef_editor_tab_anchor' ).each( function( i, anchor ) { updateAnchorCounter( $( anchor ) ); } ); }; this.initAsEmpty = /** * @param {Boolean} * currentPageItem * @param {?String} * initTypeId */ function( currentPageItem, initTypeId ) { if ( !WEF_Utils.isEmpty( initTypeId ) ) WEF_Utils.assertCorrectEntityId( initTypeId ); this.entityId = null; var newTitle = i18n.dialogTitleNewElement + ' — ' + originalTitle; dialog.attr( 'title', newTitle ); dialog.dialog( 'option', 'title', newTitle ); if ( labelsEditor != null ) { labelsEditor.initAsEmpty( currentPageItem ); } $.each( claimEditorsTables, /** * @param {number} * i * @param {WEF_ClaimEditorsTable} * claimEditorsTable */ function( i, claimEditorsTable ) { if ( !WEF_Utils.isEmpty( initTypeId ) && claimEditorsTable.definition.code == 'P31' ) { claimEditorsTable.init( WEF_Utils.mockEntityWithType( initTypeId ) ); } else { claimEditorsTable.initAsEmpty( currentPageItem ); } } ); enableAnchorCounterUpdate = true; dialog.find( 'a.wef_editor_tab_anchor' ).each( function( i, anchor ) { updateAnchorCounter( $( anchor ) ); } ); }; this.open = function() { dialog.dialog( 'open' ); }; }; window.WEF_EditorForm = WEF_EditorForm; /** * @class */ WEF_Editor = function( dialogHtml ) { "use strict"; if ( typeof dialogHtml === 'undefined' ) { throw new Error( 'Dialog HTML is not specified' ); } this.i18n = {}; this.dialogHtml = dialogHtml; }; window.WEF_Editor = WEF_Editor; WEF_Editor.prototype.addEditButtons = /** * @param {?String} * initTypeId */ function( initTypeId ) { "use strict"; var editor = this; var li = $( document.createElement( 'li' ) ).addClass( 'plainlinks' ); $( document.createElement( 'a' ) ).css( 'cursor', 'pointer' ).click( function() { var editDeferred = editor.edit( true, undefined, initTypeId ); editDeferred.done( function() { WEF_Utils.purge(); } ); } ).text( this.i18n.menuButton ).appendTo( li ); $( '#p-tb div ul' ).append( li ); }; WEF_Editor.prototype.edit = /** * @param {!Boolean} * currentPageItem * @param {?String} * entityId * @param {?String} * entityTypeId */ function( currentPageItem, entityId, entityTypeId ) { "use strict"; if ( !WEF_Utils.isEmpty( entityId ) ) WEF_Utils.assertCorrectEntityId( entityId ); if ( !WEF_Utils.isEmpty( entityTypeId ) ) WEF_Utils.assertCorrectEntityId( entityTypeId ); var editDeferred = $.Deferred(); if ( currentPageItem ) { entityId = WEF_Utils.getEntityId(); } var editor = this; var i18n = this.i18n; if ( entityId === null ) { // empty item var editorForm = new WEF_EditorForm( editor.i18n.dialogTitle, editor.dialogHtml, editor.i18n, currentPageItem, editDeferred ); editorForm.initAsEmpty( currentPageItem, entityTypeId ); wef_LabelsCache.receiveLabels(); editorForm.open(); return editDeferred; } var statusDialog = $( document.createElement( 'div' ) ); statusDialog.attr( 'title', this.i18n.dialogTitle ); statusDialog.append( $( document.createElement( 'p' ) ).text( this.i18n.statusLoadingWikidata ) ); statusDialog.dialog(); $.ajax( { type: 'GET', url: WEF_Utils.getWikidataApiPrefix() + '&action=wbgetentities&ids=' + entityId, dataType: 'json', success: function( result ) { var editorForm = new WEF_EditorForm( editor.i18n.dialogTitle, editor.dialogHtml, editor.i18n, currentPageItem, editDeferred ); editorForm.load( result.entities[entityId] ); wef_LabelsCache.receiveLabels(); editorForm.open(); }, complete: function() { statusDialog.dialog( 'close' ); }, fail: function() { alert( i18n.errorLoadingWikidata ); editDeferred.reject( 'Unable to load from Wikidata' ); }, } ); return editDeferred; }; WEF_Editor.prototype.localize = function( i18n_prefix ) { "use strict"; WEF_Utils.localize( this.i18n, 'wef_AnyEditor_i18n_' ); WEF_Utils.localize( this.i18n, i18n_prefix ); }; WEF_Editors_Registry = function() { "use strict"; /** @type {WEF_Editor[]} */ this.registry = {}; this.registryLength = 0; }; WEF_Editors_Registry.prototype.registerEditor = function( classEntityId, wef_editor ) { if ( WEF_Utils.isEmpty( classEntityId ) ) { throw new Error( 'Illegal argument: classEntityId not provided' ); } if ( !( wef_editor instanceof WEF_Editor ) ) { throw new Error( 'Illegal argument: ' + wef_editor + ' is not instanceof WEF_Editor' ); } this.registry[classEntityId] = wef_editor; this.registryLength++; }; var wef_editors_registry = window.wef_editors_registry = new WEF_Editors_Registry(); /** @class */ var WEF_SelectEditor = function( anchor, optionPrefix, listener ) { var select = $( document.createElement( 'select' ) ).addClass( 'wef-editor-menu' ).attr( 'size', wef_editors_registry.registryLength ); select.hide(); $( document.body ).append( select ); var called = false; var _this = this; function changeF() { var value = _this.val(); if ( value !== null ) { if ( called ) { return; } called = true; _this.hide(); listener( value, wef_editors_registry.registry[value] ); } } $.each( wef_editors_registry.registry, function( id, editor ) { var jOption = $( document.createElement( 'option' ) ).attr( 'value', id ).text( optionPrefix + id ).appendTo( select ); wef_LabelsCache.getOrQueue( id, function( label, description ) { jOption.text( optionPrefix + label ); jOption.attr( 'title', description ); } ); } ); wef_LabelsCache.receiveLabels(); select.click( changeF ); select.change( changeF ); this.val = function( value ) { if ( typeof value === 'undefined' ) { return select.val(); } select.val( value ); }; this.text = function() { var option = select.find( ':selected' ); if ( option.length !== 0 ) { return option.text(); } return null; }; this.visible = false; this.hide = function() { this.visible = false; select.hide(); }; this.show = function() { called = false; anchor.after( select ); select.show().position( { my: 'left top', at: 'left bottom', of: anchor, } ); this.listener = listener; this.visible = true; }; this.toggle = function() { if ( this.visible ) { this.hide(); } else { this.show(); } }; }; fc0llzv431dhm4ayywmjh8qwtn68uvn MediaWiki:RefToolbar.js 8 8570 99909 98197 2026-11-02T19:41:26Z Maintenance script 3796 Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup) 99909 javascript text/javascript /*jshint smarttabs:true, loopfunc:true,forin:false*/ /*global mw, $, importScript */ // ____________________________________________________________________________________________ // | | // | Основано на версии 632049119 гаджета refToolbar.js | // | (https://en.wikipedia.org/w/index.php?title=MediaWiki:RefToolbar.js&oldid=795320777) | // |____________________________________________________________________________________________| // TODO: make autodate an option in the CiteTemplate object, not a preference // Global object // TODO: // * Remove this once the page is moved to a module 'ext.gadget.refToolbarDialogs' depending on 'ext.gadget.refToolbarBase' if (typeof CiteTB === 'undefined') { var CiteTB = { "Templates" : {}, // All templates "Options" : {}, // Global options "UserOptions" : {}, // User options "DefaultOptions" : {}, // Script defaults "ErrorChecks" : {} // Error check functions }; } // Only execute on edit, unless it is a user JS/CSS page // TODO: Remove tests already done by [[MediaWiki:Gadget-refToolbar.js]] if ( ( mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' ) && ( ( mw.config.get('wgNamespaceNumber') !== 2 && mw.config.get('wgNamespaceNumber') !== 4 ) || ( mw.config.get('wgPageName').indexOf('.js') === -1 && mw.config.get('wgPageName').indexOf('.css') === -1 ) ) ) { // TODO: Move this to [[MediaWiki:Gadget-refToolbarDialogs.css]] and add it to the definition of module 'ext.gadget.refToolbarDialogs' mw.util.addCSS(".cite-form-td {"+ "height: 0 !important;"+ "padding: 0.1em !important;"+ "}"); // Default options, these mainly exist so the script won't break if a new option is added CiteTB.DefaultOptions = { "date format" : "<year>-<zmonth>-<zdate>", "autodate fields" : [], "months" : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], "modal" : true, "autoparse" : false, "expandtemplates": false }; // Get an option - user settings override global which override defaults CiteTB.getOption = function(opt) { if (CiteTB.UserOptions[opt] !== undefined) { return CiteTB.UserOptions[opt]; } else if (CiteTB.Options[opt] !== undefined) { return CiteTB.Options[opt]; } return CiteTB.DefaultOptions[opt]; }; CiteTB.init = function() { /* Main stuff, build the actual toolbar structure * 1. get the template list, make the dropdown list and set up the template dialog boxes * 2. actually build the toolbar: * * A section for cites * ** dropdown for the templates (previously defined) * ** button for named refs with a dialog box * ** button for errorcheck * 3. add the whole thing to the main toolbar */ if (typeof $('div[rel=cites]')[0] !== 'undefined') { // Mystery IE bug workaround return; } $('head').trigger('reftoolbarbase'); var $target = $('#wpTextbox1'); var temlist = {}; for (var t in CiteTB.Templates) { var tem = CiteTB.Templates[t]; var sform = CiteTB.escStr(tem.shortform); var actionobj = { type: 'dialog', module: 'cite-dialog-'+sform }; var dialogobj = {}; dialogobj['cite-dialog-'+sform] = { resizeme: false, titleMsg: 'cite-dialog-'+sform, id: 'citetoolbar-'+sform, init: function() {}, html: tem.getInitial(), dialog: { width:675, open: function() { $(this).html(CiteTB.getOpenTemplate().getForm()); /** @param {jQuery.Event} e */ $('.cite-prev-parse').on( 'click', function ( e ) { e.preventDefault(); CiteTB.prevParseClick(); }); }, buttons: { 'cite-form-submit': function() { var ref = CiteTB.getRef(false, true); $(this).dialog( 'close' ); $.wikiEditor.modules.toolbar.fn.doAction( $(this).data( 'context' ), { type: 'encapsulate', options: { post: ref } }, $(this) ); }, 'cite-form-showhide': CiteTB.showHideExtra, 'cite-refpreview': function() { var ref = CiteTB.getRef(false, false); var template = CiteTB.getOpenTemplate(); var div = $("#citetoolbar-"+CiteTB.escStr(template.shortform)); div.find('.cite-preview-label').show(); div.find('.cite-ref-preview').text(ref).show(); if (CiteTB.getOption('autoparse')) { CiteTB.prevParseClick(); } else { div.find('.cite-prev-parse').show(); div.find('.cite-prev-parsed-label').hide(); div.find('.cite-preview-parsed').html(''); } }, 'wikieditor-toolbar-tool-link-cancel': function() { $(this).dialog( 'close' ); }, 'cite-form-reset': function() { CiteTB.resetForm(); } } } }; $target.wikiEditor('addDialog', dialogobj); //if (!CiteTB.getOption('modal')) { //$('#citetoolbar-'+sform).dialog('option', 'modal', false); //} temlist[sform] = {label: tem.templatename, action: actionobj }; } var refsection = { 'sections': { 'cites': { type: 'toolbar', labelMsg: 'cite-section-label', groups: { 'template': { tools: { 'template': { type: 'select', labelMsg: 'cite-template-list', list: temlist } } }, 'namedrefs': { labelMsg: 'cite-named-refs-label', tools: { 'nrefs': { type: 'button', action: { type: 'dialog', module: 'cite-toolbar-namedrefs' }, icon: '//thumb.wikimedia.org/wikipedia/commons/thumb/b/be/Nuvola_clipboard_lined.svg/60px-Nuvola_clipboard_lined.svg.png', section: 'cites', group: 'namedrefs', labelMsg: 'cite-named-refs-button' } } }, 'errorcheck': { labelMsg: 'cite-errorcheck-label', tools: { 'echeck': { type: 'button', action: { type: 'dialog', module: 'cite-toolbar-errorcheck' }, icon: '//thumb.wikimedia.org/wikipedia/commons/thumb/a/a3/Nuvola_apps_korganizer-NO.png/60px-Nuvola_apps_korganizer-NO.png', section: 'cites', group: 'errorcheck', labelMsg: 'cite-errorcheck-button' } } } } } } }; var defaultdialogs = { 'cite-toolbar-errorcheck': { titleMsg: 'cite-errorcheck-label', id: 'citetoolbar-errorcheck', resizeme: false, init: function() {}, html: '<div id="cite-namedref-loading">'+ '<img src="//upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif" />'+ '&nbsp;'+mw.usability.getMsg('cite-loading')+'</div>', dialog: { width:550, open: function() { CiteTB.loadRefs(); }, buttons: { 'cite-errorcheck-submit': function() { var errorchecks = $("input[name='cite-err-test']:checked"); var errors = []; for (var i=0; i<errorchecks.length; i++) { errors = errors.concat(CiteTB.ErrorChecks[$(errorchecks[i]).val()].run()); } CiteTB.displayErrors(errors); $(this).dialog( 'close' ); }, 'wikieditor-toolbar-tool-link-cancel': function() { $(this).dialog( 'close' ); } } } }, 'cite-toolbar-namedrefs': { titleMsg: 'cite-named-refs-title', resizeme: false, id: 'citetoolbar-namedrefs', html: '<div id="cite-namedref-loading">'+ '<img src="//upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif" />'+ '&nbsp;'+mw.usability.getMsg('cite-loading')+'</div>', init: function() {}, dialog: { width: 550, open: function() { CiteTB.loadRefs(); }, buttons: { 'cite-form-submit': function() { var refname = $("#cite-namedref-select").val(); if (refname === '') { return; } $(this).dialog( 'close' ); $.wikiEditor.modules.toolbar.fn.doAction( $(this).data( 'context' ), { type: 'encapsulate', options: { post: CiteTB.getNamedRef(refname, true) } }, $(this) ); }, 'wikieditor-toolbar-tool-link-cancel': function() { $(this).dialog( 'close' ); } } } } }; $target.wikiEditor('addDialog', defaultdialogs); $('#citetoolbar-namedrefs').off('dialogopen'); if (!CiteTB.getOption('modal')) { //$('#citetoolbar-namedrefs').dialog('option', 'modal', false); //$('#citetoolbar-errorcheck').dialog('option', 'modal', false); mw.util.addCSS(".ui-widget-overlay {"+ "display:none !important;"+ "}"); } $target.wikiEditor('addToToolbar', refsection); }; // Load local data - messages, cite templates, etc. $(document).ready( function() { switch( mw.config.get('wgUserLanguage') ) { case 'en': importScript('MediaWiki:RefToolbarMessages-en.js'); break; default: importScript('MediaWiki:RefToolbarMessages-ru.js'); } }); // Setup the main object CiteTB.mainRefList = []; CiteTB.refsLoaded = false; // REF FUNCTIONS // Actually assemble a ref from user input CiteTB.getRef = function(inneronly, forinsert) { var i; var template = CiteTB.getOpenTemplate(); var templatename = template.templatename; var res = ''; var refobj = {'shorttag':false}; if (!inneronly) { var group = $('#cite-'+CiteTB.escStr(template.shortform)+'-group').val(); var refname = $('#cite-'+CiteTB.escStr(template.shortform)+'-name').val(); res += '<ref'; if (refname) { refname = $.trim(refname); res+=' name='+CiteTB.getQuotedString(refname); refobj.refname = refname; } if (group) { group = $.trim(group); res+=' group='+CiteTB.getQuotedString(group); refobj.refgroup = group; } res+='>'; } var content ='{{'+templatename; for( g in template.incrementables ) { group = template.incrementables[g]; for (i=1; i<=group.val; i++) { for (j=0; j<group.fields.length; j++) { var fieldname = group.fields[j].field; var fieldid = fieldname.replace('<N>', i.toString()); var field = $('#cite-'+CiteTB.escStr(template.shortform)+'-'+fieldid).val(); if (field) { content+='|'+fieldid+'='; content+= $.trim(field); } } } } for( i=0; i<template.basic.length; i++ ) { if (template.basic[i].increment_group) { continue; } var fieldname = template.basic[i].field; var field = $('#cite-'+CiteTB.escStr(template.shortform)+'-'+fieldname).val(); if (field) { content+='|'+fieldname+'='; content+= $.trim(field); } } if ($('#cite-form-status').val() !== 'closed') { for( i=0; i<template.extra.length; i++ ) { if (template.extra[i].increment_group) { continue; } var fieldname = template.extra[i].field; var field = $('#cite-'+CiteTB.escStr(template.shortform)+'-'+fieldname).val(); if (field) { content+='|'+fieldname+'='; content+= $.trim(field); } } } content+= '}}'; res+=content; refobj.content = content; if (!inneronly) { res+= '</ref>'; } if (forinsert) { CiteTB.mainRefList.push(refobj); } return res; }; // Make a reference to a named ref CiteTB.getNamedRef = function(refname, forinsert) { if (forinsert) { CiteTB.mainRefList.push( {'shorttag':true, 'refname':refname} ); } return '<ref name='+CiteTB.getQuotedString(refname)+' />'; }; // Function to load the ref list CiteTB.loadRefs = function() { if (CiteTB.refsLoaded) { return; } CiteTB.getPageText(CiteTB.loadRefsInternal); }; // Function that actually loads the list from the page text CiteTB.loadRefsInternal = function(text) { // What this does: extract first name/group extract second name/group shorttag inner content var refsregex = /< *ref(?: +(name|group) *= *(?:"([^"]*?)"|'([^']*?)'|([^ '"\/\>]*?)) *)? *(?: +(name|group) *= *(?:"([^"]*?)"|'([^']*?)'|([^ '"\/\>]*?)) *)? *(?:\/ *>|>((?:.|\n)*?)< *\/ *ref *>)/gim; // This should work regardless of the quoting used for names/groups and for linebreaks in the inner content while (true) { var ref = refsregex.exec(text); if (ref === null) { break; } var refobj = {}; if (ref[9]) { // Content + short tag check //alert('"'+ref[9]+'"'); refobj.content = ref[9]; refobj.shorttag = false; } else { refobj.shorttag = true; } if (ref[1] !== '') { // First name/group if (ref[2]) { refobj['ref'+ref[1]] = ref[2]; } else if (ref[3]) { refobj['ref'+ref[1]] = ref[3]; } else { refobj['ref'+ref[1]] = ref[4]; } } if (ref[5] !== '') { // Second name/group if (ref[6]) { refobj['ref'+ref[5]] = ref[6]; } else if (ref[7]) { refobj['ref'+ref[5]] = ref[7]; } else { refobj['ref'+ref[5]] = ref[8]; } } CiteTB.mainRefList.push(refobj); } CiteTB.refsLoaded = true; CiteTB.setupErrorCheck(); CiteTB.setupNamedRefs(); }; // AJAX FUNCTIONS // Parse some wikitext and hand it off to a callback function CiteTB.parse = function(text, callback) { $.post( mw.util.wikiScript( 'api' ), {action:'parse', title:mw.config.get('wgPageName'), text:text, prop:'text', format:'json'}, function(data) { var html = data.parse.text['*']; callback(html); }, 'json' ); }; // Use the API to expand templates on some text CiteTB.expandtemplates = function(text, callback) { $.post( mw.util.wikiScript( 'api' ), {action:'expandtemplates', title:mw.config.get('wgPageName'), text:text, format:'json'}, function(data) { var restext = data.expandtemplates['*']; callback(restext); }, 'json' ); }; // Function to get the page text CiteTB.getPageText = function(callback) { if (CiteTB.getOption('expandtemplates')) { CiteTB.expandtemplates($('#wpTextbox1').wikiEditor('getContents').text(), callback); } else { callback($('#wpTextbox1').wikiEditor('getContents').text()); } }; // Autofill a template from an ID (ISBN, DOI, PMID, URL) CiteTB.initAutofill = function() { var elemid = $(this).attr('id'); var res = /^cite\-auto\-(.*?)\-(.*)\-(.*)$/.exec(elemid); var tem = res[1]; var field = res[2]; var autotype = res[3]; var id = $('#cite-'+tem+'-'+field).val(); if (!id) { return false; } var url = '//tools.wmflabs.org/reftoolbar/lookup.php?'; url+=autotype+'='+encodeURIComponent(id); url+='&template='+encodeURIComponent(tem); var s = document.createElement('script'); s.setAttribute('src', url); s.setAttribute('type', 'text/javascript'); document.getElementsByTagName('head')[0].appendChild(s); return false; }; // Callback for autofill //TODO: Autofill the URL, at least for DOI CiteTB.autoFill = function(data, template, type) { var cl = 'cite-'+template+'-'; var i,j, coauthors; $('.'+cl+'title').val(data.title); // Fill in authors if (data.authors && data.authors.length > 0) { if ($('.'+cl+'last-incr-1').length != 0) { var classes = $('.'+cl+'last-incr-1').eq(0).attr('class').split(/\s+/); var group = false; var patt = /cite-[^-]*?-incr-(.*)/ for (var c=0; c<classes.length; c++) { if (patt.exec(classes[c])) { group = patt.exec(classes[c])[1]; break; } } $('.'+cl+'last-incr-1').val(data.authors[0][0]) $('.'+cl+'first-incr-1').val(data.authors[0][1]) elemid = '#cite-incr-'+template+'-'+group; for (var i=2; i<data.authors.length+1; i++) { $(elemid).click(); $('.'+cl+'last-incr-'+i.toString()).val(data.authors[i-1][0]) $('.'+cl+'first-incr-'+i.toString()).val(data.authors[i-1][1]) } } else if ($('.'+cl+'author-incr-1').length != 0) { var classes = $('.'+cl+'author-incr-1').eq(0).attr('class').split(/\s+/); var group = false; var patt = /cite-[^-]*?-incr-(.*)/ for (var c=0; c<classes.length; c++) { if (patt.exec(classes[c])) { group = patt.exec(classes[c])[1]; break; } } $('.'+cl+'author-incr-1').val(data.authors[0].join(', ')) elemid = '#cite-incr-'+template+'-'+group; for (var i=2; i<data.authors.length+1; i++) { $(elemid).click(); $('.'+cl+'author-incr-'+i.toString()).val(data.authors[i-1].join(', ')) } } else if ($('.'+cl+'last1').length != 0) { for(i=0; data.authors && i<data.authors.length; i++) { if ($('.'+cl+'last'+(i+1)).length) { $('.'+cl+'last'+(i+1)).val(data.authors[i][0]); $('.'+cl+'first'+(i+1)).val(data.authors[i][1]); } else { coauthors = []; for(j=i; j<data.authors.length; j++) { coauthors.push(data.authors[j].join(', ')); } $('.'+cl+'coauthors').val(coauthors.join('; ')); break; } } } else if($('.'+cl+'author1').length !== 0) { for(i=0; data.authors && i<data.authors.length; i++) { if ($('.'+cl+'author'+(i+1)).length) { $('.'+cl+'author'+(i+1)).val(data.authors[i].join(', ')); } else { coauthors = []; for(j=i; j<data.authors.length; j++) { coauthors.push(data.authors[j].join(', ')); } $('.'+cl+'coauthors').val(coauthors.join('; ')); break; } } } else { var authors = []; for(i=0; data.authors && i<data.authors.length; i++) { authors.push(data.authors[i].join(', ')); } $('.'+cl+'authors').val(authors.join('; ')); } } if (type === 'pmid' || type === 'doi') { if (data.date && (data.fulldate || !$('.'+cl+'month').length)) { var DT = new Date(data.date); var useday = /\d{4}-\d{2}-\d{2}/.test(data.date); var usemonth = /\d{4}-\d{2}/.test(data.date); $('.'+cl+'date').val(CiteTB.formatDate(DT, useday, usemonth)); } else if (!data.fulldate && $('.'+cl+'month').length && $('.'+cl+'year').length) { if (data.month) { // lookup.php sets month to false if it isn't provided $('.'+cl+'month').val( CiteTB.getOption('months')[parseInt(data.month)-1] ); } $('.'+cl+'year').val(data.year); } else { $('.'+cl+'date').val(data.date); } $('.'+cl+'journal').val(data.journal); $('.'+cl+'volume').val(data.volume); $('.'+cl+'issue').val(data.issue); $('.'+cl+'pages').val(data.pages); if (type === 'pmid' && data.doi) { $('.'+cl+'doi').val(data.doi); } } else if (type === 'isbn') { $('.'+cl+'publisher').val(data.publisher); $('.'+cl+'location').val(data.location); $('.'+cl+'year').val(data.year); $('.'+cl+'edition').val(data.edition); } else if (type === 'url') { if (data.date) { var DT = new Date(data.date); var useday = /\d{4}-\d{2}-\d{2}/.test(data.date) && template !== 'book'; var usemonth = /\d{4}-\d{2}/.test(data.date) && template !== 'book'; var yearOrDate = (template === 'book') ? 'year' : 'date'; $('.'+cl+yearOrDate).val(CiteTB.formatDate(DT, useday, usemonth)); } $('.'+cl+'journal').val(data.journal); $('.'+cl+'volume').val(data.volume); $('.'+cl+'issue').val(data.issue); $('.'+cl+'pages').val(data.pages); $('.'+cl+'publisher').val(data.publisher); $('.'+cl+'edition').val(data.edition); $('.'+cl+'isbn').val(data.isbn); $('.'+cl+'issn').val(data.issn); $('.'+cl+'doi').val(data.doi); // "en-US" isn't a valid value for the language parameter if (data.language && data.language !== 'ru-RU' ) { $('.'+cl+'language').val(data.language); } $('.'+cl+'chapter').val(data.chapter); } }; // FORM DIALOG FUNCTIONS // Add new incrementable fields CiteTB.incrementFields = function() { template = CiteTB.getOpenTemplate(); var currentrow = $(this).parents('tr')[0]; $(this).prev().css('width', '100%') $(this).detach(); var elemid = $(this).attr('id'); var res = /^cite\-incr\-(.*?)\-(.*)$/.exec(elemid); group = res[2]; increments = template.incrementables[group]; fields = increments.fields; incrval = increments.val+1; template.incrementables[group].val += 1; trs = template.makeFormInner(fields, false); trs.reverse(); for (var i=0; i<trs.length; i++) { $(currentrow).after(trs[i]); } }; // fill the accessdate param with the current date CiteTB.fillAccessdate = function() { var elemid = $(this).attr('id'); var res = /^cite\-date\-(.*?)\-(.*)$/.exec(elemid); var id = res[1]; var field = res[2]; var DT = new Date(); var datestr = CiteTB.formatDate(DT); $('#cite-'+id+'-'+field).val(datestr); return false; }; CiteTB.formatDate = function(DT, useday, usemonth) { if (typeof useday == "undefined") { useday = true; } if (typeof usemonth == "undefined") { usemonth = true; } var datestr = CiteTB.getOption('date format'); var zmonth = ''; var month = DT.getUTCMonth()+1; if (month < 10) { zmonth = "0"+month.toString(); } else { zmonth = month.toString(); } month = month.toString(); var zdate = ''; var date = DT.getUTCDate(); if (date < 10) { zdate = "0"+date.toString(); } else { zdate = date.toString(); } date = date.toString(); if (useday) { datestr = datestr.replace('<date>', date); datestr = datestr.replace('<zdate>', zdate); } else { datestr = datestr.replace('<date>', ''); datestr = datestr.replace('<zdate>', ''); } if (usemonth) { datestr = datestr.replace('<month>', month); datestr = datestr.replace('<zmonth>', zmonth); datestr = datestr.replace('<monthname>', CiteTB.getOption('months')[DT.getUTCMonth()]); } else { datestr = datestr.replace('<month>', ''); datestr = datestr.replace('<zmonth>', ''); datestr = datestr.replace('<monthname>', ''); } datestr = datestr.replace('<year>', DT.getUTCFullYear().toString()); return datestr.replace(/^[ \/\-\,\.]*(.*?)[ \/\-\,\.]*$/g, "$1"); // Cleanup any dangling spaces or connectors that might result from omitting date/month }; // Function called after the ref list is loaded, to actually set the contents of the named ref dialog // Until the list is loaded, its just a "Loading" placeholder CiteTB.setupNamedRefs = function() { var names = [], i; for( i=0; i<CiteTB.mainRefList.length; i++) { if (!CiteTB.mainRefList[i].shorttag && CiteTB.mainRefList[i].refname) { names.push(CiteTB.mainRefList[i]); } } var stuff = $('<div>'); $('#citetoolbar-namedrefs').html( stuff ); if (names.length === 0) { stuff.html(mw.usability.getMsg('cite-no-namedrefs')); } else { stuff.html(mw.usability.getMsg('cite-namedrefs-intro')); var select = $('<select id="cite-namedref-select">'); select.append($('<option value="" />').text(mw.usability.getMsg('cite-named-refs-dropdown'))); for(i=0; i<names.length; i++) { select.append($('<option />').text(names[i].refname)); } stuff.after(select); select.before('<br />'); var prevlabel = $('<div id="cite-nref-preview-label" style="display:none;" />').html(mw.usability.getMsg('cite-raw-preview')); select.after(prevlabel); prevlabel.before("<br /><br />"); prevlabel.after('<div id="cite-namedref-preview" style="padding:0.5em; font-size:110%" />'); var parselabel = $('<span id="cite-parsed-label" style="display:none;" />').html(mw.usability.getMsg('cite-parsed-label')); $('#cite-namedref-preview').after(parselabel); parselabel.after('<div id="cite-namedref-parsed" style="padding-bottom:0.5em; font-size:110%" />'); var link = $('<a href="#" id="cite-nref-parse" style="margin:0 1em 0 1em; display:none; color:darkblue" />'); link.html(mw.usability.getMsg('cite-form-parse')); $('#cite-namedref-parsed').after(link); $("#cite-namedref-select").on( 'change', CiteTB.namedRefSelectClick); $('#cite-nref-parse').on( 'click', CiteTB.nrefParseClick); } }; // Function to get the errorcheck form HTML CiteTB.setupErrorCheck = function() { var form = $('<div id="cite-errorcheck-heading" />').html(mw.usability.getMsg('cite-errorcheck-heading')); var ul = $("<ul id='cite-errcheck-list' />"); var test; for (var t in CiteTB.ErrorChecks) { test = CiteTB.ErrorChecks[t]; ul.append(test.getRow()); } form.append(ul); $('#citetoolbar-errorcheck').html(form); }; // Callback function for parsed preview CiteTB.fillNrefPreview = function(parsed) { $('#cite-parsed-label').show(); $('#cite-namedref-parsed').html(parsed); }; // Click handler for the named-ref parsed preview CiteTB.nrefParseClick = function() { var choice = $("#cite-namedref-select").val(); if (choice === '') { $('#cite-parsed-label').hide(); $('#cite-namedref-parsed').text(''); return false; } $('#cite-nref-parse').hide(); for( var i=0; i<CiteTB.mainRefList.length; i++) { if (!CiteTB.mainRefList[i].shorttag && CiteTB.mainRefList[i].refname == choice) { CiteTB.parse(CiteTB.mainRefList[i].content, CiteTB.fillNrefPreview); return false; } } }; // Click handler for the named-ref dropdown CiteTB.lastnamedrefchoice = ''; CiteTB.namedRefSelectClick = function() { var choice = $("#cite-namedref-select").val(); if (CiteTB.lastnamedrefchoice == choice) { return; } CiteTB.lastnamedrefchoice = choice; $('#cite-parsed-label').hide(); $('#cite-namedref-parsed').text(''); if (choice === '') { $('#cite-nref-preview-label').hide(); $('#cite-namedref-preview').text(''); $('#cite-nref-parse').hide(); return; } for( var i=0; i<CiteTB.mainRefList.length; i++) { if (!CiteTB.mainRefList[i].shorttag && CiteTB.mainRefList[i].refname == choice) { $('#cite-nref-preview-label').show(); $('#cite-namedref-preview').text(CiteTB.mainRefList[i].content); if (CiteTB.getOption('autoparse')) { CiteTB.nrefParseClick(); } else { $('#cite-nref-parse').show(); } } } }; // callback function for parsed preview CiteTB.fillTemplatePreview = function(text) { var template = CiteTB.getOpenTemplate(); var div = $("#citetoolbar-"+CiteTB.escStr(template.shortform)); div.find('.cite-prev-parsed-label').show(); div.find('.cite-preview-parsed').html(text); }; // Click handler for template parsed preview CiteTB.prevParseClick = function() { var ref = CiteTB.getRef(true, false); var template = CiteTB.getOpenTemplate(); var div = $("#citetoolbar-"+CiteTB.escStr(template.shortform)); div.find('.cite-prev-parse').hide(); CiteTB.parse(ref, CiteTB.fillTemplatePreview); }; // Show/hide the extra fields in the dialog box CiteTB.showHideExtra = function() { var template = CiteTB.getOpenTemplate(); var div = $("#citetoolbar-"+CiteTB.escStr(template.shortform)); var setting = div.find(".cite-form-status").val(); if ( setting === 'closed' ) { div.find(".cite-form-status").val('open'); div.find('.cite-extra-fields').show(1, function() { // jQuery adds "display:block", which screws things up div.find('.cite-extra-fields').attr('style', 'width:100%; background-color:transparent;'); }); } else { div.find(".cite-form-status").val('closed'); div.find('.cite-extra-fields').hide(); } }; // Resets form fields and previews // Resets form fields and previews CiteTB.resetForm = function() { var template = CiteTB.getOpenTemplate(); var div = $("#citetoolbar-"+CiteTB.escStr(template.shortform)); div.html(template.getForm()); }; // STRING UTILITY FUNCTIONS // Returns a string quoted as necessary for name/group attributes CiteTB.getQuotedString = function(s) { var sq = /\'/.test(s); // single quotes var dq = /\"/.test(s); // double quotes if (!sq && !dq) { // Always quotes for non-latin alphabet return '"'+s+'"'; } else if (!dq) { // Can use double quotes return '"'+s+'"'; } else if (!sq) { // Can use single quotes return "'"+s+"'"; } else { // Has double and single quotes s = s.replace(/\"/g, '\''); return '"'+s+'"'; } }; // Fix up strings for output - capitalize first char, replace underscores with spaces CiteTB.fixStr = function(s) { s = s.slice(0,1).toUpperCase() + s.slice(1); s = s.replace('_',' '); return s; }; // Escape spaces and quotes for use in HTML classes/ids CiteTB.escStr = function(s) { return s.replace(' ', '-').replace("'", "\'").replace('"', '\"'); }; // MISC FUNCTIONS // Determine which template form is open, and get the template object for it CiteTB.getOpenTemplate = function() { var dialogs = $(".ui-dialog-content.ui-widget-content:visible"); var templatename = $(dialogs[0]).find(".cite-template").val(); return CiteTB.Templates[templatename]; }; // Display the report for the error checks CiteTB.displayErrors = function(errors) { $('#cite-err-report').remove(); var table = $('<table id="cite-err-report" style="width:100%; border:1px solid #A9A9A9; background-color:#FFEFD5; padding:0.25em; margin-top:0.5em" />'); $('#editpage-copywarn').before(table); var tr; var tr1 = $('<tr style="width:100%" />'); var th1 = $('<th style="width:60%; font-size:110%" />').html(mw.usability.getMsg('cite-err-report-heading')); var th2 = $('<th style="text-align:right; width:40%" />'); var im = $('<img />').attr('src', '//thumb.wikimedia.org/wikipedia/commons/thumb/5/55/Gtk-stop.svg/20px-Gtk-stop.svg.png'); im.attr('alt', mw.usability.getMsg('cite-err-report-close')).attr('title', mw.usability.getMsg('cite-err-report-close')); var ad = $('<a id="cite-err-check-close" />').attr('href', '#'); ad.append(im); th2.append(ad); tr1.append(th1).append(th2); table.append(tr1); $('#cite-err-check-close').on('click', function() { $('#cite-err-report').remove(); }); if (errors.length === 0) { tr = $('<tr style="width:100%;" />'); var td = $('<td style="text-align:center; margin:1.5px;" />').html(mw.usability.getMsg('cite-err-report-empty')); tr.append(td); table.append(tr); return; } for(var e in errors) { var err = errors[e]; tr = $('<tr style="width:100%;" />'); var td1 = $('<td style="border: 1px solid black; margin:1.5px; width:60%" />').html(err.err); var td2 = $('<td style="border: 1px solid black; margin:1.5px; width:40%" />').html(mw.usability.getMsg(err.msg)); tr.append(td1).append(td2); table.append(tr); } }; } // End of code loaded only on edit 4x8b4nd8vzcrt287wbtgwlggpo11c5k MediaWiki:Gadget-wikificator.js 8 12230 99907 78254 2026-11-02T19:41:23Z Maintenance script 3796 Use thumb.wikimedia.org for thumbnails ([[phab:T427465]], Operator: Ladsgroup) 99907 javascript text/javascript // <nowiki> ( function () { var wmFullText = 'Викификатор обработает ВЕСЬ текст на этой странице. Продолжить?', wmTalkPage = 'Викификатор не обрабатывает страницы обсуждения целиком.\n\nВыделите ваше сообщение — обработано будет только оно'; window.wfPlugins = window.wfPlugins || []; window.wfPluginsT = window.wfPluginsT || []; // Function takes an input or text as an argument. If it is absent, it uses $( '#wpTextbox1' ) // as an input. window.Wikify = function ( inputOrText ) { 'use strict'; var text, isInput, $input, caretPosition, textScroll, txt = '', hidden = [], winScroll = document.documentElement.scrollTop, $CodeMirrorVscrollbar = $( '.CodeMirror-vscrollbar' ); // Check what's in the first parameter if ( typeof inputOrText === 'string' ) { text = inputOrText; } else { isInput = ( inputOrText && ( ( inputOrText.nodeType && inputOrText.value !== undefined ) || // node ( inputOrText.prop && inputOrText.prop( 'nodeType' ) ) // jQuery object ) ); $input = $( isInput ? inputOrText : '#wpTextbox1' ); } // FUNCTIONS function r( r1, r2 ) { txt = txt.replace( r1, r2 ); } function hide( re ) { r( re, function ( s ) { return '\x01' + hidden.push( s ) + '\x02'; } ); } function hideTag ( tag ) { hide( new RegExp( '<' + tag + '( [^>]+)?>[\\s\\S]+?<\\/' + tag + '>', 'gi' ) ); } function hideTemplates() { hide( /\{\{([^{]\{?)+?\}\}/g ); var pos = 0, stack = [], tpl, left, right; while ( true ) { left = txt.indexOf( '{{', pos ); right = txt.indexOf( '}}', pos ); if ( left === -1 && right === -1 && !stack.length ) { break; } if ( left !== -1 && ( left < right || right === -1 ) ) { stack.push( left ); pos = left + 2; } else { left = stack.pop(); if ( typeof left === 'undefined' ) { if ( right === -1 ) { pos += 2; continue; } else { left = 0; } } if ( right === -1 ) { right = txt.length; } right += 2; tpl = txt.substring( left, right ); txt = txt.substring( 0, left ) + '\x01' + hidden.push( tpl ) + '\x02' + txt.substr( right ); pos = right - tpl.length; } } } function processLink( link, left, right ) { left = left.replace( /[ _\u00A0]+/g, ' ' ).trim(); if ( left.match( /^(?:Категория|Файл) ?:/ ) ) { return '[[' + left + '|' + right + ']]'; } right = right.replace( / {2,}/g, ' ' ).trim(); var inLink = right.substr( 0, left.length ); var afterLink = right.substr( left.length ); var uniLeft = left.substr( 0, 1 ).toUpperCase() + left.substr( 1 ); var uniRight = ( right.substr( 0, 1 ).toUpperCase() + right.substr( 1 ) ).replace( /[_\u00A0]/g, ' ' ); if ( uniRight.indexOf( uniLeft ) === 0 && afterLink.match( /^[a-zа-яё]*$/ ) ) { return '[[' + inLink + ']]' + afterLink; } else { return '[[' + left + '|' + right + ']]'; } } function processText() { var i, u = '\u00A0'; // non-breaking space if ( mw.config.get( 'wgNamespaceNumber' ) % 2 || mw.config.get( 'wgNamespaceNumber' ) === 4 ) { // is talk page var sigs = txt.match( /\d\d:\d\d, \d\d? \S{3,8} 20\d\d \(UTC\)/g ); if ( sigs && sigs.length > 1 ) { alert( wmTalkPage ); return; } } hideTag( 'nowiki' ); hideTag( 'pre' ); hideTag( 'source' ); hideTag( 'syntaxhighlight' ); hideTag( 'templatedata' ); hideTag( 'code' ); hideTag( 'kbd' ); hideTag( 'tt' ); hideTag( 'graph' ); hideTag( 'hiero' ); hideTag( 'math' ); hideTag( 'timeline' ); hideTag( 'chem' ); hideTag( 'score' ); hideTag( 'categorytree' ); hideTag( 'inputbox' ); hideTag( 'mapframe' ); hideTag( 'maplink' ); r( /\{\{(?:ттун|subst):(?:[уУ]дар(?:ение)?|')\}\}/g, '\u0301' ); r( /( |\n|\r)+\{\{(·|•|\*)\}\}/g, '{{$2}}' ); // before {{·/•/*}}, usually in templates r( /\{\{\s*[Шш]аблон:([\s\S]+?)\}\}/g, '{{$1}}' ); r( /(\{\{\s*)(?:reflist|список примечаний)(\s*[\|\}])/ig, '$1баянар$2' ); r( /[\u00A0 ]+(\{\{\s*([Rr]ef-[a-z\-]+?|[Ee]n icon|[Cc]hecked|[Vv]|[Аа]хтармишун)\}\})/g, '$1' ); r( /<[\/\\]?(hr|br)( [^\/\\>]+?)? ?[\/\\]?>/gi, '<$1$2>' ); r( /(\| *Координаты[ _А-ЯЁа-яё]*= *)(\d+(?:[.,]\d+)?)[,/] ?(\d+(?:[.,]\d+)?(?=\s))/g, function ( s, m1, m2, m3 ) { return m1 + ( +parseFloat( m2.replace( ',', '.' ) ).toFixed( 4 )) + '/' + ( +parseFloat( m3.replace( ',', '.' ) ).toFixed( 4 ) ); }); r( /<noinclude>\s*(\{\{[dD]ocpage\}\})\s*<\/noinclude>/g, '$1' ); r( /(\| *(?:pp?|S|s|с|c|страницы\d?|pages\d?|seite\d?|alleseiten|листы\d?|том|volume|band|выпуск|issue|heft|номер|столбцы\d?|columns\d?|kolonnen\d?|серия год) *= *)(\d+)[\u00A0 ]?(?:-{1,3}|—) ?(\d+)/g, '$1$2—$3' ); r( /(\| *йис *= *)(\d{4})[\u00A0 ]?(?:-{1,3}|—) ?(\d{4})/g, '$1$2—$3' ); r( /(\[\[[^\{\]|\n]+){{!}}([^\{\]|\n]+\]\])/g, '$1|$2' ); for ( i in window.wfPluginsT ) { if ( window.wfPluginsT.hasOwnProperty( i ) ) { window.wfPluginsT[i]( txt, r ); } } hideTemplates(); hide( /^[ \t].*/mg ); hide( /(https?|ftp|news|nntp|telnet|irc|gopher):\/\/[^\s\[\]<>"]+ ?/gi ); hide( /^#(redirect|перенапр(авление)?)/i ); hideTag( 'gallery' ); r( / +(\n|\r)/g, '$1' ); // spaces at EOL txt = '\n' + txt + '\n'; // LINKS r( /(\[\[:?)(category|категория):( *)/ig, '$1Категория:' ); r( /(\[\[:?)(module|модуль):( *)/ig, '$1Модуль:' ); r( /(\[\[:?)(template|шаблон):( *)/ig, '$1Шаблон:' ); r( /(\[\[:?)(image|изображение|file|файл):( *)/ig, '$1Файл:' ); // Linked years, centuries and ranges r( /(\(|\s)(\[\[[12]?\d{3}\]\])[\u00A0 ]?(-{1,3}|–|—) ?(\[\[[12]?\d{3}\]\])(\W)/g, '$1$2—$4$5' ); r( /(\[\[[12]?\d{3}\]\]) ?(гг?\.)/g, '$1' + u + '$2' ); r( /(\(|\s)(\[\[[IVX]{1,5}\]\])[\u00A0 ]?(-{1,3}|–|—) ?(\[\[[IVX]{1,5}\]\])(\W)/g, '$1$2—$4$5' ); r( /(\[\[[IVX]{1,5}\]\]) ?(вв?\.)/g, '$1' + u + '$2' ); r( /\[\[(\d+)\]\]\sйис/g, '[[$1' + u + 'йис]]' ); r( /\[\[(\d+)\sйис\|\1\]\]\sйис/g, '[[$1' + u + 'йис]]' ); r( /\[\[(\d+)\sйис\|\1\sйис([а-я]{0,3})\]\]/g, '[[$1' + u + 'йис]]$2' ); r( /\[\[((\d+)(?: (?:йис )?в [\wa-яёА-ЯЁ ]+\|\2)?)\]\][\u00A0 ](йис[ан-яё]*)/g, '[[$1' + u + '$3]]' ); r( /\[\[([XVI]+)\]\]\sвишйис/g, '[[$1' + u + 'вишйис]]' ); r( /\[\[([XVI]+)\sвишйис\|\1\]\]\sвишйис/g, '[[$1' + u + 'вишйис]]' ); r( /\[\[([XVI]+)\sвишйис\|\1\sвишйис([а-я]{0,3})\]\]/g, '[[$1' + u + 'вишйис]]$2' ); r( /\[\[(([XVI]+) вишйис\|\2)\]\][\u00A0 ]вишйис/g, '[[$2' + u + 'вишйис]]' ); // Nice links r( /(\[\[[^|[\]]*)[\u00AD\u200E\u200F]+([^\[\]]*\]\])/g, '$1$2' ); // Soft Hyphen & DirMark r( /\[\[ *([^|[\]]+?) *\| *('''''|'''|'')([^'|[\]]*)\2 *]]/g, '$2[[$1|$3]]$2' ); // move fomatting out of link text r( /\[\[([^|[\]\n]+)\|([^|[\]\n]+)\]\]/g, processLink ); // link shortening r( /\[\[ *([^|[\]]+)([^|\[\]()]+?) *\| *\1 *\]\]\2/g, '[[$1$2]]' ); // text repetition after link r( /\[\[ *(?!Файл:|Категория:)([a-zA-Zа-яёА-ЯЁ\u00A0-\u00FF %!\"$&'()*,\-—.\/0-9:;=?\\@\^_`’~]+) *\| *([^\|\[\]]+) *\]\]([a-zа-яё]+)/g, '[[$1|$2$3]]' ); // " hide( /\[\[[^\]|]+/g); // only link part // TAGS r( /<<(\S.+\S)>>/g, '"$1"' ); // << >> r( /(su[pb]>)-(\d)/g, '$1−$2' ); // ->minus r( /<(b|strong)>(.*?)<\/(b|strong)>/gi, "'''$2'''" ); r( /<(i|em)>(.*?)<\/(i|em)>/gi, "''$2''" ); r( /^<hr ?\/?>/gim, '----' ); r( /[\u00A0 \t]*<ref(?:\s+name="")?(\s|>)/gi, '<ref$1' ); r( /(\n== *[a-zа-я\s\.:]+ *==\n+)<references *\/>/ig, '$1{' + '{баянар}}' ); hide( /<[a-z][^>]*?>/gi); hide( /^(\{\||\|\-).*/mg); // table/row def hide( /(^\||^!|!!|\|\|) *[a-z]+=[^|]+\|(?!\|)/mgi); // cell style hide( /\| +/g); // formatted cell r( /[ \t\u00A0]{2,}/g, ' ' ); // double spaces // Entities etc. → Unicode chars if ( mw.config.get( 'wgNamespaceNumber' ) !== 10 ) { r( /&(#x[0-9a-f]{2,4}|#[0-9]{3,4}|[0-9a-z]{2,8});/gi, function ( s ) { var t = document.createElement( 'textarea' ); t.innerHTML = s; var c = t.value; if ( c.length === 1 && c.charCodeAt( 0 ) > 127 || s === '&#x20;' ) { return c; } return s; }); } r( /\(tm\)/gi, '™' ); r( /\.\.\./g, '…' ); r( /(^|[^+])\+-(?!\+|-)/g, '$1±' ); r( /~=/g, '≈' ); r( /\^2(\D)/g, '²$1' ); r( /\^3(\D)/g, '³$1' ); r( /(\s)кв\.\s*(дм|см|мм|мкм|нм|км|м)(\s)/g, '$1' + u + '$2²$3' ); r( /(\s)куб\.\s*(дм|см|мм|мкм|нм|км|м)(\s)/g, '$1' + u + '$2³$3' ); r( /((?:^|[\s"])\d+(?:[\.,]\d+)?)\s*[xх]\s*(\d+(?:[\.,]\d+)?)\s*([мm]{1,2}(?:[\s"\.,;?!]|$))/g, '$1×$2' + u + '$3' ); r( /\s+×\s+/g, u + '×' + u ); r( /([\wа-яА-ЯёЁ])'(?=[\wа-яА-ЯёЁ])/g, '$1’' ); // ' r( /№№/g, '№' ); // Headings r( /^(=+)[ \t\f\v]*(.*?)[ \t\f\v]*=+$/gm, '$1 $2 $1' ); // add spaces inside r( /([^\r\n])(\r?\n==.+==\r?\n)/g, '$1\n$2' ); // add empty line before r( /(==.+==)[\r\n]{2,}(?!=)/g, '$1\n' ); // remove empty line after r( /^== (см(\.?|отр(и|ите|еть))|see) ?(также|ещ[её]|also|more) ==$/gmi, '== ГьакӀни килига ==' ); r( /^== баянар ==$/gmi, '== Баянар ==' ); r( /^== алукьунар ==$/gmi, '== ЭлячӀунар ==' ); r( /^== элячӀунар ==$/gmi, '== ЭлячӀунар ==' ); r( /^== элячIунар ==$/gmi, '== ЭлячӀунар ==' ); r( /^== (?:(.+[^.])\.|(.+):) ==$/gm, '== $1$2 ==' ); r( /^== '''(?!.*'''.*''')(.+)''' ==$/gm, '== $1 ==' ); r( /«|»|“|”|„/g, '"' ); // temp // Hyphens and en dashes to pretty dashes r( /–/g, '-' ); // &ndash; -> hyphen r( /(\s)-{1,3} /g, '$1— ' ); // hyphen -> &mdash; r( /(\d)--(\d)/g, '$1—$2' ); // -> &mdash; r( /(\s)-(\d)/g, '$1−$2' ); // hyphen -> minus // Palochka // Меняем I на палочку r(/(К|к)\I/g, '$1Ӏ') r(/(П|п)\I/g, '$1Ӏ') r(/(Т|т)\I/g, '$1Ӏ') r(/(Ц|ц)\I/g, '$1Ӏ') r(/(Ч|ч)\I/g, '$1Ӏ') // Меняем І на палочку r(/(К|к)\І/g, '$1Ӏ') r(/(П|п)\І/g, '$1Ӏ') r(/(Т|т)\І/g, '$1Ӏ') r(/(Ц|ц)\І/g, '$1Ӏ') r(/(Ч|ч)\І/g, '$1Ӏ') // Меняем 1 на палочку r(/(К|к)1/g, '$1Ӏ') r(/(П|п)1/g, '$1Ӏ') r(/(Т|т)1/g, '$1Ӏ') r(/(Ц|ц)1/g, '$1Ӏ') r(/(Ч|ч)1/g, '$1Ӏ') // Меняем l на палочку r(/(К|к)\l/g, '$1Ӏ') r(/(П|п)\l/g, '$1Ӏ') r(/(Т|т)\l/g, '$1Ӏ') r(/(Ц|ц)\l/g, '$1Ӏ') r(/(Ч|ч)\l/g, '$1Ӏ') // Year and century ranges r( /(\(|\s)([12]?\d{3})[\u00A0 ]?(-{1,3}|—) ?([12]?\d{3})(?![\wА-ЯЁа-яё]|-[^ех]|-[ех][\wА-ЯЁа-яё])/g, '$1$2—$4' ); r( /([12]?\d{3}) ?(йй?\.)/g, '$1' + u + '$2' ); r( /(\(|\s)([IVX]{1,5})[\u00A0 ]?(-{1,3}|—) ?([IVX]{1,5})(?![\w\-])/g, '$1$2—$4' ); r( /([IVX]{1,5}) ?(вй?\.)/g, '$1' + u + '$2' ); // Reductions r( /(Т|т)\.\s?е\./g, '$1о есть' ); r( /(Т|т)\.\s?к\./g, '$1ак как' ); r( /(В|в)\sт\. ?ч\./g, '$1 том числе' ); r( /(И|и)\sт\.\s?д\./g, '$1' + u + 'т.' + u + 'д.' ); r( /(И|и)\sт\.\s?п\./g, '$1' + u + 'т.' + u + 'п.' ); r( /(Т|т)\.\s?н\./g, '$1.' + u + 'н.' ); r( /(И|и)\.\s?о\./g, '$1.' + u + 'о.' ); r( /с\.\s?ш\./g, 'с.' + u + 'ш.' ); r( /ю\.\s?ш\./g, 'ю.' + u + 'ш.' ); r( /в\.\s?д\./g, 'в.' + u + 'д.' ); r( /з\.\s?д\./g, 'з.' + u + 'д.' ); r( /л\.\s?с\./g, 'л.' + u + 'с.' ); r( /а\.\s?е\.\s?м\./g, 'а.' + u + 'е.' + u + 'м.' ); r( /а\.\s?е\./g, 'а.' + u + 'е.' ); r( /мм\sрт\.\s?ст\./g, 'мм' + u + 'рт.' + u + 'ст.' ); r( /н\.\s?э(\.|(?=\s))/g, 'н.' + u + 'э.' ); r( /(Д|д)(о|\.)\sн\.\s?э\./g, '$1о' + u + 'н.' + u + 'э.' ); r( /(\d)[\u00A0 ]?(млн|млрд|трлн|(?:м|с|д|к)?м|[км]г)\.?(?=[,;.]| "?[а-яё\-]|\s*\|)/g, '$1' + u + '$2' ); r( /(\d)[\u00A0 ](тыс)([^\.А-Яа-яЁё])/g, '$1' + u + '$2.$3' ); r( /ISBN:\s?(?=[\d\-]{8,17})/, 'ISBN ' ); // Insert/delete spaces r( /^([#*:]+)[ \t\f\v]*(?!\{\|)([^ \t\f\v*#:;])/gm, '$1 $2' ); // space after #*: unless before table r( /(\S)[\u00A0 \t](-{1,3}|—)[\u00A0 \t](\S)/g, '$1' + u + '— $3' ); r( /([А-ЯЁ]\.) ?([А-ЯЁ]\.) ?([А-ЯЁ][а-яё])/g, '$1' + u + '$2' + u + '$3' ); r( /([А-ЯЁ]\.)([А-ЯЁ]\.)/g, '$1 $2' ); r( /([а-яё]"?\)?[\.\?!:])((?:\x01\d+\x02\|)?(?:[A-QS-ZА-ЯЁ]|R(?!u\b)))/g, '$1 $2' ); // "word. Word"; don't change in cases like "Газета.Ru" r( /([)"a-zа-яё\]²³])\s*([,:])([\[(a-zа-яё])/g, '$1$2 $3' ); // "word, word", "word: word"; except ":" r( /([)a-zа-яё\]²³])\s*([,:])"/g, '$1$2 "' ); r( /([)"a-zа-яё\]²³])[ \u00A0\t]([,;])\s([\[("a-zа-яё])/g, '$1$2 $3' ); r( /([^%\/\wА-Яа-яЁё]\d+?(?:[\.,]\d+?)?) ?([%‰])(?!-[А-Яа-яЁё])/g, '$1' + u + '$2' ); //5 % r( /(\d) ([%‰])(?=-[А-Яа-яЁё])/g, '$1$2' ); //5%-й r( /([№§])(\s*)(\d)/g, '$1' + u + '$3' ); // inside () r( /\( +/g, '(' ); r( / +\)/g, ')' ); // Temperature r( /([\s\d=≈≠≤≥<>—("'|])([+±−\-]?\d+?(?:[.,]\d+?)?)(([ °\^*]| [°\^*])(C|F))(?=[\s"').,;!?|\x01])/gm, '$1$2' + u + '°$5' ); // ' // Dot → comma in numbers r( /(\s\d+)\.(\d+[\u00A0 ]*[%‰°×])/gi, '$1,$2' ); // Plugins for ( i in window.wfPlugins ) { if ( window.wfPlugins.hasOwnProperty( i ) ) { window.wfPlugins[i]( txt, r ); } } // "" → «» for ( i = 1; i <= 2; i++ ) { r( /([\s\x02!|#'"\/([{;+\-])"([^"]*)([^\s"([{|])"([^a-zа-яё])/ig, '$1«$2$3»$4' ); // " } while ( /«[^»]*«/.test( txt ) ) { r( /«([^»]*)«([^»]*)»/g, '«$1„$2“' ); } function unhide( s, num ) { return hidden[ num - 1 ]; } while ( txt.match( /\x01\d+\x02/ ) ) { r( /\x01(\d+)\x02/g, unhide ); } txt = txt.substr( 1, txt.length - 2 ); // compensation for "txt = '\n' + txt + '\n';" } function processAllText() { txt = $input ? $input.textSelection( 'getContents' ) : text; processText(); if ( $input ) { r( /^[\n\r]+/, '' ); // 2017 wikitext editor adds an empty line to the end with every text replacement // Remove the following block when [[phab:T198010]] is fixed. if ( window.ve && ve.init && ve.init.target && ve.init.target.active ) { r( /[\n\r]+$/, '' ); } $input.textSelection( 'setContents', txt ); if ( caretPosition ) { $input.textSelection( 'setSelection', { start: caretPosition[0] > txt.length ? txt.length : caretPosition[0] } ); } } else { text = txt; } if ( window.auto_comment && window.insertSummary && !document.editform.wpSection.value ) { window.insertSummary( 'викификатор' ); } } // MAIN CODE if ( $input ) { $input.focus(); caretPosition = $input.textSelection( 'getCaretPosition', { startAndEnd: true } ); if ( caretPosition ) { textScroll = ( $CodeMirrorVscrollbar.length ? $CodeMirrorVscrollbar : $input ) .scrollTop(); if ( caretPosition[0] === caretPosition[1] ) { processAllText(); } else { txt = $input.textSelection( 'getSelection' ); processText(); // replaceSelection doesn't work with MediaWiki 1.30 in case this gadget is loaded // from other wiki $input.textSelection( 'encapsulateSelection', { replace: true, peri: txt } ); // In CodeMirror, the selection isn't preserved, so we do it explicitly $input.textSelection( 'setSelection', { start: caretPosition[0], end: caretPosition[0] + txt.length } ); } ( $CodeMirrorVscrollbar.length ? $CodeMirrorVscrollbar : $input ) .scrollTop( textScroll ); // If something went wrong } else if ( confirm( wmFullText ) ) { processAllText(); } } else { processAllText(); return text; } // scroll back, for 2017 wikitext editor, IE, Opera document.documentElement.scrollTop = winScroll; }; function registerWikificatorTool() { registerTool( { name: 'wikificator', position: 100, title: 'Викификатор', label: 'Викификатор — автоматик текстдин туькӀуьрун', callback: Wikify, classic: { icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png', }, visual: { icon: '//thumb.wikimedia.org/wikipedia/commons/thumb/4/41/Wikificator_VE_icon.svg/20px-Wikificator_VE_icon.svg.png', modes: [ 'source' ], addRightAway: true, }, } ); } if ( mw.config.get( 'wgServerName' ) === 'ru.wikipedia.org' ) { registerWikificatorTool(); } else { $.when( mw.loader.using( [ 'mediawiki.util', 'user.options' ] ), $.getScript( 'https://ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-registerTool.js&action=raw&ctype=text/javascript' ) ).done( registerWikificatorTool ); } }() ); // </nowiki> 5ue4iv17o77a4p9t4wd0bbcq3jo3p3e