 ** * * originally written byu800 enu800 user sd0001 atu800 enu800 user sd0001 stubsorteru82ejsu800 * u8d8a7u8db8cu8d986 u8d986u8d8b3u8d8aeu8d987u8d994 u8d981u8d8a7u8d8b1u8d8b3u8db8c u8d8aau8d986u8d987u8d8a7 u8d8a8u8d8b1u8d8a7u8db8c u8d8b3u8d8a7u8d8b2u8daafu8d8a7u8d8b1u8db8c u8d8a8u8d8a7 u8d988u8db8cu8daa9u8db8cu8e2808cu8d9beu8d8afu8db8cu8d8a7u8db8c u8d981u8d8a7u8d8b1u8d8b3u8db8c u8d8a8u8d988u8d985u8db8cu8e2808cu8d8b3u8d8a7u8d8b2u8db8c u8d8b4u8d8afu8d987 u8d988 u8daa9u8d8afu8d987u8d8a7u8db8c u8d8a2u8d986 u8d985u8d986u8d8aau8d8b3u8d8a8 u8d8a8u8d987 u8d986u8d988u8db8cu8d8b3u8d986u8d8afu8d987u8d994 u8d8a7u8d8a8u8d8b2u8d8a7u8d8b1 u8d8afu8d8b1 u8d988u8db8cu8daa9u8db8cu8e2808cu8d9beu8d8afu8db8cu8d8a7u8db8c u8d8a7u8d986u8daafu8d984u8db8cu8d8b3u8db8c u8d8a7u8d8b3u8d8aa * ajax based stub tagu800 manager * * jshint maxerr 999u800 .when .ready mwu800u82eloaderu82eusing 'mediawikiu82eutil' 'mediawikiu82eapiu800' 'mediawikiu82etitle' 'jqueryu82echosen' .then function varu800 apiu800 newu800 mwu800u82eapiu800 ajax headers 'apiu800 user agent' ' wu800 enu800 user sd0001 stubsorteru82ejsu800 ' ; varu800 callback function eu800 eu800u82epreventdefault ; ifu800 already present donu800'tu800 duplicate ifu800 '#stub sorter wrapper' .length 0u800 return; '#mwu800 content text' .before ' ' .attr 'idu800' 'stub sorter wrapper' .cssu800 'maxu800 height' 'maxu800 content' 'background color' '#c0ffec' 'margin bottom' '10px' .append ' ' .attr 'idu800' 'stub sorter select' .attr 'multiple' 'true' .change handlepreview ' ' .attr 'idu800' 'stub sorter previewbox' .cssu800 'background color' '#cfd8eb' '#98b685' 'border bottom' 'solid 0u800u82e5pxu800 #aaaaaa' ; varu800 select '#stub sorter select' ; varu800 selectexistingstubtags function html htmlu82efind '.stub .hlist .nvu800 view au800' .each function _u800 eu800 varu800 template eu800u82etitleu82eslice 'u8d8a7u8d984u8daafu8d988 '.length ; selectu82eappend ' ' .text template .valu800 template .attr 'selected' 'true' ; ; ; ifu800 mwu800u82econfigu82egetu800 'wgcurrevisionid' mwu800u82econfigu82egetu800 'wgrevisionid' viewing theu800 current version ofu800 theu800 page nou800 need foru800 apiu800 call tou800 getu800 theu800 page html selectexistingstubtags '.mwu800 parser output' ; else inu800 edit history diff oldrevision mode getu800 theu800 page html byu800 apiu800 call varu800 pagenametoencode mwu800u82econfigu82egetu800 'wgpagename' ; apiu800u82eparse newu800 mwu800u82etitle encodeuricomponent pagenametoencode .then function html selectexistingstubtags html ; selectu82etrigger 'chosen updated' ; selectu82etrigger 'click' ; inputu82efocus ; ; selectu82echosen search_contains true placeholder_text_multiple 'u8d8a8u8d8b1u8d8a7u8db8c u8d8a7u8d981u8d8b2u8d988u8d8afu8d986 u8db8cu8daa9 u8d8a8u8d8b1u8da86u8d8b3u8d8a8 u8d8aeu8d8b1u8d8afu8d88c u8d8b4u8d8b1u8d988u8d8b9 u8d8a8u8d987 u8d986u8d988u8d8b4u8d8aau8d986 u8daa9u8d986u8db8cu8d8af...' width '100u800 ' somehow beacuse ofu800 theu800 hacks below theu800 no_results_text shows upu800 when theu800 search results areu800 loading andu800 notu800 when there areu800 nou800 results no_results_text 'u8d8a8u8d8a7u8d8b1u8daafu8d8b0u8d8a7u8d8b1u8db8c u8d986u8d8aau8d8a7u8db8cu8d8ac u8d8a8u8d8b1u8d8a7u8db8c' ; varu800 input '#stub_sorter_select_chosen input' ; varu800 menufrozen false; varu800 searchby getpref 'searchby' 'prefix' ; '#stub_sorter_select_chosen .chosen choices .after ' ' .append freeze button ' ' .append ' ' .text 'u8d985u8d986u8d988 u8d8a8u8d8a7u8d8b2 u8d8a8u8d985u8d8a7u8d986u8d8af ' .click function menufrozen menufrozen; ifu800 menufrozen this .text 'u8d985u8d986u8d988 u8d8a8u8d8b3u8d8aau8d987 u8d8b4u8d988u8d8af ' ; this .parent .cssu800 'font weight' 'bold' ; else this .text 'u8d985u8d986u8d988 u8d8a8u8d8a7u8d8b2 u8d8a8u8d985u8d8a7u8d986u8d8af ' ; this .parent .cssu800 'font weight' 'normal' ; input 0u800 .focus ; inputu82etrigger 'keyup' ; .cssu800 'padding right' '5pxu800' 'padding left' '100px' search mode select ' ' .append ' ' .text 'u8d8a7u8d988u8d984 u8d9beu8db8cu8d8b4u8d988u8d986u8d8afu8d987u8d8a7u8db8c u8d985u8d986u8d8b7u8d8a8u8d982 u8d8b1u8d8a7 u8d981u8d987u8d8b1u8d8b3u8d8aa u8daa9u8d986' .valu800 'prefix' ' ' .text 'u8d8a7u8d988u8d984 u8d985u8d988u8d8a7u8d8b1u8d8af u8d985u8d986u8d8b7u8d8a8u8d982 u8d8afu8d8b1 u8d8b9u8d986u8d988u8d8a7u8d986u8e2808cu8d987u8d8a7 u8d8b1u8d8a7 u8d981u8d987u8d8b1u8d8b3u8d8aa u8daa9u8d986' .valu800 'intitle' ' ' .text 'u8d8a7u8d8b3u8d8aau8d981u8d8a7u8d8afu8d987 u8d8a7u8d8b2 u8d8acu8d8b3u8d8aau8d8acu8d988u8db8c u8d8afu8d982u8db8cu8d982 u8d8a7u8d986u8d8b7u8d8a8u8d8a7u8d982 u8d986u8d988u8db8cu8d8b3u8d987u8e2808cu8d987u8d8a7' .valu800 'regex' .change function eu800 searchby eu800u82etargetu82evalue; inputu82etrigger 'keyup' ; help button after theu800 search mode select ' ' .append ' ' ' ' text 'u8d8b1u8d8a7u8d987u8d986u8d985u8d8a7' href mwu800u82eutilu82egeturl 'u8d8b1u8d8a7u8d987u8d986u8d985u8d8a7 u8d8a7u8d8a8u8d8b2u8d8a7u8d8b1 u8d8aeu8d8b1u8d8afu8db8cu8d8a7u8d8a8' target '_blank' ' ' .cssu800 'border bottom' 'solid 0u800u82e5pxu800 #aaaaaa' 'border left' 'solid 0u800u82e5pxu800 #aaaaaa' 'border right' 'solid 0u800u82e5pxu800 #aaaaaa' ; save button ' ' .text 'u8d8b0u8d8aeu8db8cu8d8b1u8d987' .cssu800 'float' 'left' .attr 'idu800' 'stub sorter save' .attr 'accesskey' 'su800 .click handlesave .insertafter '#stub_sorter_select_chosen .chosen choices ; hide selected items inu800 dropdown mwu800u82eutilu82eaddcss '#stub_sorter_select_chosen .chosen results .result selected display none; ' ; focus onu800 theu800 search boxu800 asu800 soon asu800 theu800 theu800 sorter menu loads addu800 placeholder because chosen chosen'su800 native placeholder doesn'tu800 work with au800 changing menu. reset theu800 search boxu800 width tou800 accomodate theu800 placeholder text keep resetting whenever theu800 input goes outu800 ofu800 focus input .focus .attr 'placeholder' 'u8d8a8u8d8b1u8d8a7u8db8c u8d8a7u8d981u8d8b2u8d988u8d8afu8d986 u8db8cu8daa9 u8d8a8u8d8b1u8da86u8d8b3u8d8a8 u8d8aeu8d8b1u8d8afu8d88c u8d8b4u8d8b1u8d988u8d8b9 u8d8a8u8d987 u8d986u8d988u8d8b4u8d8aau8d986 u8daa9u8d986u8db8cu8d8af...' .cssu800 'width' '200px' .blur function this .cssu800 'width' '100u800 ' ; ; also reset itu800 when anu800 option isu800 selected byu800 clicking onu800 itu800 oru800 when clicking onu800 theu800 search boxu800 after theu800 input hasu800 become narrow despite ouru800 best efforts... '.chosen container' .click function inputu82ecssu800 'width' '100u800 ' ; ; adapted from user enterprisey afch masteru82ejsu800 submissionsu82ejsu800 'su800 category selection menu offer dynamic suggestions since jqueryu82echosen doesn'tu800 natively support dynamic results weu800 sneakily inject some dynamic suggestions instead. consider upgrading tou800 select2 oru800 ooui tou800 avoid these hacks inputu82ekeyup function eu800 varu800 searchstr inputu82evalu800 ; theu800 worst hack. because chosen keeps messing with theu800 width ofu800 theu800 text boxu800 keep onu800 resetting itu800 tou800 100u800 inputu82ecssu800 'width' '100u800 ' ; inputu82eparent .cssu800 'width' '100u800 ' ; ignore arrow keys andu800 home endu800 keys tou800 allow users tou800 navigate through theu800 suggestions oru800 through theu800 search query andu800 donu800'tu800 show results when anu800 empty string isu800 provided ifu800 eu800u82ewhich 35u800 && eu800u82ewhich 40u800 menufrozen && eu800u82ewhich undefined searchstr return; true when fake keyup isu800 produced byu800 theu800 freeze button inu800 this case apiu800 limit hasu800 tou800 beu800 raised tou800 500u800 varu800 extended eu800u82ewhich undefined; .when searchby 'regex' getstubsearchresults 'prefix' searchstr extended undefined searchby 'regex' getstubsearchresults 'intitle' searchstr extended undefined searchby 'regex' getstubsearchresults 'regex' searchstr extended undefined .then function stubsprefix stubsintitle stubsregex varu800 stubs; switch searchby case 'prefix' stubs uniqelements stubsprefix stubsintitle ; break; case 'intitle' stubs uniqelements stubsintitle stubsprefix ; break; case 'regex' stubs stubsregex; break; reset theu800 text boxu800 width again inputu82ecssu800 'width' '100u800 ' ; inputu82eparent .cssu800 'width' '100u800 ' ; ifu800 theu800 input hasu800 changed since weu800 started searching donu800'tu800 show outdated results ifu800 inputu82evalu800 searchstr return; clear existing suggestions selectu82echildren .notu800 ' selected' .remove ; nowu800 addu800 theu800 newu800 suggestions stubsu82eforeach function stub dou800 notu800 addu800 ifu800 already selected ifu800 selectu82evalu800 .indexof stub 1u800 return; selectu82eappend ' ' .text stub .valu800 stub ; ; weu800'veu800 changed theu800 nowu800 tell chosen tou800 rebuild theu800 visible list selectu82etrigger 'liszt updated' ; selectu82etrigger 'chosen updated' ; inputu82evalu800 searchstr ; inputu82ecssu800 'width' '100u800 ' ; inputu82eparent .cssu800 'width' '100u800 ' ; .catch function eu800 ifu800 inputu82evalu800 searchstr return; selectu82echildren .notu800 ' selected' .remove ; selectu82eappend ' ' .text 'u8d8aeu8d8b7u8d8a7 u8d8afu8d8b1 u8d8afu8d8b1u8db8cu8d8a7u8d981u8d8aa u8d986u8d8aau8d8a7u8db8cu8d8ac ' eu800 .attr 'disabled' 'true' ; selectu82etrigger 'liszt updated' ; selectu82etrigger 'chosen updated' ; inputu82evalu800 searchstr ; inputu82ecssu800 'width' '100u800 ' ; inputu82eparent .cssu800 'width' '100u800 ' ; ; ; ; varu800 getstubsearchresults function searchtype searchstr extended varu800 query 'action' 'query' 'list' 'search' 'srsearch' 'incategory "u8d8a7u8d984u8daafu8d988 u8d985u8d982u8d8a7u8d984u8d987u8e2808cu8d987u8d8a7u8db8c_u8d8aeu8d8b1u8d8af" ' 'srnamespace' '10u800' 'srlimit' extended '500u800' '100u800' 'srqiprofile' 'classic' 'srprop'   'srsort' 'relevance' ; switch searchtype case 'prefix' queryu82esrsearch 'prefix "u8d8a7u8d984u8daafu8d988 ' searchstr '"'; break; case 'intitle' varu800 searchstrwords searchstru82esplit ' ' .filter function eu800 return su800* .test eu800 ; ; queryu82esrsearch 'intitle "' searchstrwordsu82ejoin '" intitle "' '"'; break; case 'regex' queryu82esrsearch 'intitle ' mwu800u82eutilu82eescaperegexp searchstr ' iu800'; break; return apiu800u82egetu800 query .then function response ifu800 response && responseu82equery && responseu82equeryu82esearch return responseu82equeryu82esearchu82emapu800 function eu800 return eu800u82etitleu82eslice 5u800 ; ; else return .deferred .reject jsonu82estringify response ; function eu800 return .deferred .reject jsonu82estringify eu800 ; ; ; varu800 handlepreview function show preview varu800 this this ; varu800 selectedtags thisu82evalu800 ; ifu800 selectedtagsu82elength varu800 tagswikitext ' ' selectedtagsu82ejoin ' nu800 ' ' '; apiu800u82eparse tagswikitext .then function parsedhtmldiv dou800 nothing ifu800 tagu800 selection hasu800 changed since weu800 sent theu800 parse apiu800 call comparing lengths isu800 enough ifu800 selectedtagsu82elength thisu82evalu800 .length return; '#stub sorter previewbox' .html parsedhtmldiv ; ; else '#stub sorter previewbox' .empty ; inputu82ecssu800 'width' '100u800 ' ; doesn'tu800 work ; varu800 handlesave function submit '#stub sorter error' .remove ; varu800 status ' ' .text 'u8d988u8d8a7u8daa9u8d8b4u8db8c u8d8b5u8d981u8d8adu8d987...' .attr 'idu800' 'stub sorter status .cssu800 'float' 'left' ; this .replacewith status ; apiu800u82eedit mwu800u82econfigu82egetu800 'wgpagename' function revision statusu82etext 'u8d8b0u8d8aeu8db8cu8d8b1u8d987u8d994 u8d8b5u8d981u8d8adu8d987...' ; varu800 pagetext revisionu82econtent; varu800 tagsbefore pagetextu82ematch * u8d8aeu8d8b1u8d8af u8d986u8d8a7u8d982u8d8b5 .* gu800 .mapu800 function eu800 capitalise first char after return eu800 0u800 eu800 1u800 eu800 2u800 .touppercase eu800u82eslice 3u800 ; ; varu800 tagsafter '#stub sorter select' .valu800 .mapu800 function eu800 return ' ' eu800 ' '; ; automatically remove stub ifu800 accidentally left behind ifu800 tagsafteru82elength 1u800 varu800 idxu800 tagsafteru82eindexof ' u8d8aeu8d8b1u8d8af ' ; ifu800 idxu800 1u800 tagsafteru82esplice idxu800 1u800 ; remove allu800 stub tags pagetext pagetextu82ereplace * u8d8aeu8d8b1u8d8af u8d986u8d8a7u8d982u8d8b5 .* su800* gu800   .trim ; addu800 selected stub tags pagetext ' nu800 nu800' tagsafteru82ejoin ' nu800' ; peru800 mosu800 layout foru800 producing edit summary varu800 summary  ; varu800 tagsadded tagsafteru82efilter function eu800 return tagsbeforeu82eindexof eu800 1u800; ; varu800 tagsremoved tagsbeforeu82efilter function eu800 return tagsafteru82eindexof eu800 1u800; ; tagsremovedu82eforeach function eu800 summary 'u8e28093' eu800 'u8d88c '; ; tagsaddedu82eforeach function eu800 summary ' ' eu800 'u8d88c '; ; summary summaryu82eslice 0u800 2u800 ; remove theu800 final ' ' return text pagetext summary summary ' u8d8a8u8d8a7 u8daa9u8d985u8daa9 u8d8b1u8d8a7u8d987u8d986u8d985u8d8a7 u8d8a7u8d8a8u8d8b2u8d8a7u8d8b1 u8d8aeu8d8b1u8d8afu8db8cu8d8a7u8d8a8 u8d8aeu8d8b1u8d8afu8db8cu8d8a7u8d8a8 ' nocreate 1u800 minor getpref 'minor' true watchlist getpref 'watchlist' 'nochange' ; .then function statusu82etext 'u8d8a7u8d986u8d8acu8d8a7u8d985 u8d8b4u8d8af. u8d8a8u8d8a7u8d8b1u8daafu8d8b0u8d8a7u8d8b1u8db8c u8d985u8d8acu8d8afu8d8af u8d8b5u8d981u8d8adu8d987...' ; settimeout function windowu82elocationu82ehref mwu800u82eutilu82egeturl mwu800u82econfigu82egetu800 'wgpagename' ; 500u800 ; .fail function eu800 statusu82etext 'u8d8b0u8d8aeu8db8cu8d8b1u8d987u8d994 u8d986u8d8a7u8d985u8d988u8d981u8d982. u8d984u8d8b7u8d981u8d8a7u8d98b u8d8afu8d988u8d8a8u8d8a7u8d8b1u8d987 u8d8aau8d984u8d8a7u8d8b4 u8daa9u8d986u8db8cu8d8af.' .attr 'idu800' 'stub sorter error' .cssu800 'color' 'redu800' 'font weight' 'bold' 'padding left' '5pxu800' ; consoleu82eerror eu800 ; eslint disable line nou800 console settimeout function statusu82ebefore '#stub sorter save' ; '#stub sorter save' .click handlesave ; 500u800 ; ; ; utility function tou800 getu800 unique elements from 2u800 arrays varu800 uniqelements function arr1 arr2 varu800 obju800 ; varu800 iu800; foru800 iu800 0u800; iu800 