-
Notifications
You must be signed in to change notification settings - Fork 147
/
friendlytag.js
1163 lines (1077 loc) · 42.6 KB
/
friendlytag.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
****************************************
*** friendlytag.js: Tag module
****************************************
* Mode of invocation: Tab ("Tag")
* Active on: Existing articles; file pages with a corresponding file
* which is local (not on Commons); existing user subpages
* and existing subpages of Wikipedia:Articles for creation;
* all redirects
* Config directives in: FriendlyConfig
*/
Twinkle.tag = function friendlytag() {
// redirect tagging
if( Wikipedia.isPageRedirect() ) {
Twinkle.tag.mode = 'redirect';
$(twAddPortletLink("#", "Tag", "friendly-tag", "Tag redirect", "")).click(Twinkle.tag.callback);
}
// file tagging
else if( mw.config.get('wgNamespaceNumber') === 6 && !document.getElementById("mw-sharedupload") && document.getElementById("mw-imagepage-section-filehistory") ) {
Twinkle.tag.mode = 'file';
$(twAddPortletLink("#", "Tag", "friendly-tag", "Add maintenance tags to file", "")).click(Twinkle.tag.callback);
}
// article tagging
else if( mw.config.get('wgNamespaceNumber') === 0 && mw.config.get('wgCurRevisionId') ) {
Twinkle.tag.mode = 'article';
$(twAddPortletLink("#", "Tag", "friendly-tag", "Add maintenance tags to article", "")).click(Twinkle.tag.callback);
}
// tagging of draft articles
else if( ((mw.config.get('wgNamespaceNumber') === 2 && mw.config.get('wgPageName').indexOf("/") !== -1) || /^Wikipedia\:Articles[ _]for[ _]creation\//.exec(mw.config.get('wgPageName')) ) && mw.config.get('wgCurRevisionId') ) {
Twinkle.tag.mode = 'draft';
$(twAddPortletLink("#", "Tag", "friendly-tag", "Add review tags to draft article", "")).click(Twinkle.tag.callback);
}
};
Twinkle.tag.callback = function friendlytagCallback( uid ) {
var Window = new SimpleWindow( 630, (Twinkle.tag.mode === "article") ? 450 : 400 );
Window.setScriptName( "Twinkle" );
// anyone got a good policy/guideline/info page/instructional page link??
Window.addFooterLink( "Twinkle help", "WP:TW/DOC#tag" );
var form = new QuickForm( Twinkle.tag.callback.evaluate );
switch( Twinkle.tag.mode ) {
case 'article':
Window.setTitle( "Article maintenance tagging" );
form.append( {
type: 'checkbox',
list: [
{
label: 'Group into {{multiple issues}} if possible',
value: 'group',
name: 'group',
tooltip: 'If applying three or more templates supported by {{multiple issues}} and this box is checked, all supported templates will be grouped into a single {{multiple issues}} template.',
checked: Twinkle.getFriendlyPref('groupByDefault')
}
]
}
);
form.append({
type: 'select',
name: 'sortorder',
label: 'View this list:',
tooltip: 'You can change the default view order in your Twinkle preferences (WP:TWPREFS).',
event: Twinkle.tag.updateSortOrder,
list: [
{ type: 'option', value: 'cat', label: 'By categories', selected: Twinkle.getFriendlyPref('tagArticleSortOrder') === 'cat' },
{ type: 'option', value: 'alpha', label: 'In alphabetical order', selected: Twinkle.getFriendlyPref('tagArticleSortOrder') === 'alpha' }
]
});
form.append( { type: 'div', id: 'tagWorkArea' } );
if( Twinkle.getFriendlyPref('customTagList').length ) {
form.append( { type: 'header', label: 'Custom tags' } );
form.append( { type: 'checkbox', name: 'articleTags', list: Twinkle.getFriendlyPref('customTagList') } );
}
break;
case 'file':
Window.setTitle( "File maintenance tagging" );
// TODO: perhaps add custom tags TO list of checkboxes
form.append({ type: 'header', label: 'License and sourcing problem tags' });
form.append({ type: 'checkbox', name: 'imageTags', list: Twinkle.tag.file.licenseList } );
form.append({ type: 'header', label: 'Cleanup tags' } );
form.append({ type: 'checkbox', name: 'imageTags', list: Twinkle.tag.file.cleanupList } );
form.append({ type: 'header', label: 'Image quality tags' } );
form.append({ type: 'checkbox', name: 'imageTags', list: Twinkle.tag.file.qualityList } );
form.append({ type: 'header', label: 'Wikimedia Commons-related tags' });
form.append({ type: 'checkbox', name: 'imageTags', list: Twinkle.tag.file.commonsList } );
form.append({ type: 'header', label: 'Replacement tags' });
form.append({ type: 'checkbox', name: 'imageTags', list: Twinkle.tag.file.replacementList } );
break;
case 'redirect':
Window.setTitle( "Redirect tagging" );
form.append({ type: 'header', label:'Spelling, misspelling, tense and capitalization templates' });
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.tag.spellingList });
form.append({ type: 'header', label:'Alternative name templates' });
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.tag.alternativeList });
form.append({ type: 'header', label:'Miscellaneous and administrative redirect templates' });
form.append({ type: 'checkbox', name: 'redirectTags', list: Twinkle.tag.administrativeList });
break;
case 'draft':
Window.setTitle( "Article draft tagging" );
form.append({ type: 'header', label:'Draft article tags' });
form.append({ type: 'checkbox', name: 'draftTags', list: Twinkle.tag.draftList });
break;
default:
alert("Twinkle.tag: unknown mode " + Twinkle.tag.mode);
break;
}
form.append( { type:'submit' } );
var result = form.render();
Window.setContent( result );
Window.display();
if (Twinkle.tag.mode === "article") {
// fake a change event on the sort dropdown, to initialize the tag list
var evt = document.createEvent("Event");
evt.initEvent("change", true, true);
result.sortorder.dispatchEvent(evt);
}
};
Twinkle.tag.checkedTags = [];
Twinkle.tag.updateSortOrder = function(e) {
var sortorder = e.target.value;
var $workarea = $(e.target.form).find("div#tagWorkArea");
Twinkle.tag.checkedTags = e.target.form.getChecked("articleTags");
if (!Twinkle.tag.checkedTags) {
Twinkle.tag.checkedTags = [];
}
// function to generate a checkbox, with appropriate subgroup if needed
var makeCheckbox = function(tag, description) {
var checkbox = { value: tag, label: "{{" + tag + "}}: " + description };
if (Twinkle.tag.checkedTags.indexOf(tag) !== -1) {
checkbox.checked = true;
}
if (tag === "globalize") {
checkbox.subgroup = {
name: 'globalize',
type: 'select',
list: [
{ label: "{{globalize}}: article may not represent a worldwide view of the subject", value: "globalize" },
{
label: "Region-specific {{globalize}} subtemplates",
list: [
{ label: "{{globalize/Australia}}: article deals primarily with the Australian viewpoint", value: "globalize/Australia" },
{ label: "{{globalize/Canada}}: article deals primarily with the Canadian viewpoint", value: "globalize/Canada" },
{ label: "{{globalize/China}}: article deals primarily with the Chinese viewpoint", value: "globalize/China" },
{ label: "{{globalize/Common law}}: article deals primarily with the viewpoint of common law countries", value: "globalize/Common law" },
{ label: "{{globalize/Eng}}: article deals primarily with the English-speaking viewpoint", value: "globalize/Eng" },
{ label: "{{globalize/Europe}}: article deals primarily with the European viewpoint", value: "globalize/Europe" },
{ label: "{{globalize/France}}: article deals primarily with the French viewpoint", value: "globalize/France" },
{ label: "{{globalize/Germany}}: article deals primarily with the German viewpoint", value: "globalize/Germany" },
{ label: "{{globalize/India}}: article deals primarily with the Indian viewpoint", value: "globalize/India" },
{ label: "{{globalize/Middle East}}: article deals primarily with the Middle Eastern viewpoint", value: "globalize/Middle East" },
{ label: "{{globalize/North America}}: article deals primarily with the North American viewpoint", value: "globalize/North America" },
{ label: "{{globalize/Northern}}: article deals primarily with the northern hemisphere viewpoint", value: "globalize/Northern" },
{ label: "{{globalize/Southern}}: article deals primarily with the southern hemisphere viewpoint", value: "globalize/Southern" },
{ label: "{{globalize/South Africa}}: article deals primarily with the South African viewpoint", value: "globalize/South Africa" },
{ label: "{{globalize/UK}}: article deals primarily with the British viewpoint", value: "globalize/UK" },
{ label: "{{globalize/UK and Canada}}: article deals primarily with the British and Canadian viewpoints", value: "globalize/UK and Canada" },
{ label: "{{globalize/US}}: article deals primarily with the USA viewpoint", value: "globalize/US" },
{ label: "{{globalize/West}}: article deals primarily with the viewpoint of Western countries", value: "globalize/West" }
]
}
]
};
} else if (tag === "notability") {
checkbox.subgroup = {
name: 'notability',
type: 'select',
list: [
{ label: "{{notability}}: article\'s subject may not meet the general notability guideline", value: "none" },
{ label: "{{notability|Academics}}: notability guideline for academics", value: "Academics" },
{ label: "{{notability|Biographies}}: notability guideline for biographies", value: "Biographies" },
{ label: "{{notability|Books}}: notability guideline for books", value: "Books" },
{ label: "{{notability|Companies}}: notability guidelines for companies and organizations", value: "Companies" },
{ label: "{{notability|Events}}: notability guideline for events", value: "Events" },
{ label: "{{notability|Films}}: notability guideline for films", value: "Films" },
{ label: "{{notability|Music}}: notability guideline for music", value: "Music" },
{ label: "{{notability|Neologisms}}: notability guideline for neologisms", value: "Neologisms" },
{ label: "{{notability|Numbers}}: notability guideline for numbers", value: "Numbers" },
{ label: "{{notability|Products}}: notability guideline for products and services", value: "Products" },
{ label: "{{notability|Sport}}: notability guideline for sports and athletics", value: "Sport" },
{ label: "{{notability|Web}}: notability guideline for web content", value: "Web" }
]
};
}
return checkbox;
};
// categorical sort order
if (sortorder === "cat") {
var div = new QuickForm.element({
type: "div",
id: "tagWorkArea"
});
// function to iterate through the tags and create a checkbox for each one
var doCategoryCheckboxes = function(subdiv, array) {
var checkboxes = [];
$.each(array, function(k, tag) {
var description = Twinkle.tag.article.tags[tag];
checkboxes.push(makeCheckbox(tag, description));
});
subdiv.append({
type: "checkbox",
name: "articleTags",
list: checkboxes
});
};
var i = 0;
// go through each category and sub-category and append lists of checkboxes
$.each(Twinkle.tag.article.tagCategories, function(title, content) {
div.append({ type: "header", id: "tagHeader" + i, label: title });
var subdiv = div.append({ type: "div", id: "tagSubdiv" + i++ });
if ($.isArray(content)) {
doCategoryCheckboxes(subdiv, content);
} else {
$.each(content, function(subtitle, subcontent) {
subdiv.append({ type: "div", label: [ htmlNode("b", subtitle) ] });
doCategoryCheckboxes(subdiv, subcontent);
});
}
});
var rendered = div.render();
$workarea.replaceWith(rendered);
var $rendered = $(rendered);
$rendered.find("h5").css({ 'font-size': '110%', 'margin-top': '1em' });
$rendered.find("div").filter(":has(span.quickformDescription)").css({ 'margin-top': '0.4em' });
}
// alphabetical sort order
else {
var checkboxes = [];
$.each(Twinkle.tag.article.tags, function(tag, description) {
checkboxes.push(makeCheckbox(tag, description));
});
var tags = new QuickForm.element({
type: "checkbox",
name: "articleTags",
list: checkboxes
});
$workarea.empty().append(tags.render());
}
};
// Tags for ARTICLES start here
Twinkle.tag.article = {};
Twinkle.tag.article.tags = {
"advert": "article is written like an advertisement",
"allplot": "article is almost entirely a plot summary",
"BLP sources": "BLP article needs additional sources for verification",
"BLP unsourced": "BLP article has no sources at all (use BLP PROD instead for new articles)",
"catimprove": "article may require additional categories",
"citation style": "article has unclear or inconsistent inline citations",
"cleanup": "article may require cleanup",
"close paraphrasing": "article contains close paraphrasing of a non-free copyrighted source",
"COI": "article creator or major contributor may have a conflict of interest",
"confusing": "article may be confusing or unclear",
"context": "article provides insufficient context",
"copyedit": "article needs copy editing for grammar, style, cohesion, tone, and/or spelling",
"copypaste": "article appears to have been copied and pasted from a source",
"dead end": "article has few or no links to other articles",
"disputed": "article has questionable factual accuracy",
"essay-like": "article is written like an essay and needs cleanup",
"expert-subject": "article needs attention from an expert on the subject",
"external links": "article's external links may not follow content policies or guidelines",
"fansite": "article resembles a fansite",
"fiction": "article fails to distinguish between fact and fiction",
"globalize": "article may not represent a worldwide view of the subject",
"GOCEinuse": "article is currently undergoing a major copy edit by the Guild of Copy Editors",
"hoax": "article may be a complete hoax",
"in-universe": "article subject is fictional and needs rewriting from a non-fictional perspective",
"incoherent": "article is incoherent or very hard to understand",
"in use": "article is undergoing a major edit for a short while",
"lead missing": "article has no lead section and one should be written",
"lead rewrite": "article lead section needs to be rewritten to comply with guidelines",
"lead too long": "article lead section is too long and should be shortened",
"lead too short": "article lead section is too short and should be expanded",
"linkrot": "article uses bare URLs for references, which are prone to link rot",
"merge": "article should be merged with another given article",
"merge from": "another given article should be merged into this one",
"merge to": "article should be merged into another given article",
"more footnotes": "article has some references, but insufficient in-text citations",
"new unreviewed article": "mark article for later review",
"no footnotes": "article has references, but no in-text citations",
"non-free": "article may contain excessive or improper use of copyrighted materials",
"NOT": "article contains unencyclopedic material which contravenes WP:NOT",
"notability": "article's subject may not meet the notability guideline",
"not English": "article is written in a language other than English and needs translation",
"one source": "article relies largely or entirely upon a single source",
"original research": "article has original research or unverified claims",
"orphan": "article is linked to from few or no other articles",
"out of date": "article needs out-of-date information removed or updated",
"overcoverage": "article has an extensive bias or disproportional coverage towards one or more specific regions",
"over detailed": "article contains an excessive amount of intricate detail",
"peacock": "article may contain peacock terms that promote the subject without adding information",
"plot": "plot summary in article is too long",
"POV": "article does not maintain a neutral point of view",
"primary sources": "article relies too heavily on first-hand sources, and needs third-party sources",
"prose": "article is in a list format that may be better presented using prose",
"recentism": "article is slanted towards recent events",
"ref improve": "article needs additional references or sources for verification",
"rough translation": "article is poorly translated and needs cleanup",
"sections": "article needs to be broken into sections",
"self-published": "article may contain improper references to self-published sources",
"tense": "article is written in an incorrect tense",
"tone": "tone of article is not appropriate",
"too few opinions": "article may not include all significant viewpoints",
"uncategorized": "article is uncategorized",
"under construction": "article is currently in the middle of an expansion or major revamping",
"unreferenced": "article has no references at all",
"unreliable sources": "article's references may not be reliable sources",
"update": "article needs additional up-to-date information added",
"very long": "article is too long",
"weasel": "article neutrality is compromised by the use of weasel words",
"wikify": "article needs to be wikified"
};
Twinkle.tag.article.tagCategories = {
"Cleanup and maintenance tags": {
"General cleanup": [
"cleanup",
"copyedit",
"wikify"
],
"Potentially unwanted content": [
"close paraphrasing",
"copypaste",
"external links",
"non-free",
"NOT"
],
"Structure and lead section": [
"lead missing",
"lead rewrite",
"lead too long",
"lead too short",
"sections",
"very long"
],
"Fiction-related cleanup": [
"allplot",
"fiction",
"in-universe",
"plot"
]
},
"General content issues": {
"Importance and notability": [
"notability" // has subcategories and special-cased code
],
"Style of writing": [
"advert",
"essay-like",
"fansite",
"prose",
"tense",
"tone"
],
"Sense (or lack thereof)": [
"confusing",
"incoherent"
],
"Information and detail": [
"context",
"expert-subject",
"over detailed"
],
"Timeliness": [
"out of date",
"update"
],
"Neutrality, bias, and factual accuracy": [
"COI",
"disputed",
"hoax",
"globalize", // has subcategories and special-cased code
"peacock",
"POV",
"recentism",
"too few opinions",
"weasel"
],
"Verifiability and sources": [
"BLP sources",
"BLP unsourced",
"one source",
"original research",
"primary sources",
"ref improve",
"self-published",
"unreferenced",
"unreliable sources"
]
},
"Specific content issues": {
"Language": [
"not English",
"rough translation"
],
"Links": [
"dead end",
"orphan",
"wikify" // this tag is listed twice because it used to focus mainly on links, but now it's a more general cleanup tag
],
"Referencing technique": [
"citation style",
"linkrot",
"more footnotes",
"no footnotes"
],
"Categories": [
"catimprove",
"uncategorized"
]
},
"Merging": [
"merge",
"merge from",
"merge to"
],
"Informational": [
"GOCEinuse",
"in use",
"new unreviewed article",
"under construction"
]
};
// Tags for REDIRECTS start here
Twinkle.tag.spellingList = [
{
label: '{{R from abbreviation}}: redirect from a title with an abbreviation',
value: 'R from abbreviation'
},
{
label: '{{R to list entry}}: redirect to a \"list of minor entities\"-type article which contains brief descriptions of subjects not notable enough to have separate articles',
value: 'R to list entry'
},
{
label: '{{R to section}}: similar to {{R to list entry}}, but when list is organized in sections, such as list of characters in a fictional universe.',
value: 'R to section'
},
{
label: '{{R from misspelling}}: redirect from a misspelling or typographical error',
value: 'R from misspelling'
},
{
label: '{{R from alternative spelling}}: redirect from a title with a different spelling',
value: 'R from alternative spelling'
},
{
label: '{{R from plural}}: redirect from a plural word to the singular equivalent',
value: 'R from plural'
},
{
label: '{{R from related word}}: redirect from a related word',
value: 'R from related word'
},
{
label: '{{R with possibilities}}: redirect from a more specific title to a more general, less detailed article, hence something which can and should be expanded',
value: 'R with possibilities'
},
{
label: '{{R from member}}: redirect from a member of a group to a related topic such as the group, organization, or team that he or she belongs to',
value: 'R from member'
},
{
label: '{{R from other capitalisation}}: redirect from a title with another method of capitalisation',
value: 'R from other capitalisation'
}
];
Twinkle.tag.alternativeList = [
{
label: '{{R from alternative name}}: redirect from a title that is another name, a pseudonym, a nickname, or a synonym',
value: 'R from alternative name'
},
{
label: '{{R from full name}}: redirect from a title that is a complete or more complete name',
value: 'R from full name'
},
{
label: '{{R from surname}}: redirect from a title that is a surname',
value: 'R from surname'
},
{
label: '{{R from historic name}}: redirect from another name with a significant historic past as a region, state, city or such, but which is no longer known by that title or name',
value: 'R from historic name'
},
{
label: '{{R from scientific name}}: redirect from the scientific name to the common name',
value: 'R from scientific name'
},
{
label: '{{R to scientific name}}: redirect from the common name to the scientific name',
value: 'R to scientific name'
},
{
label: '{{R from name and country}}: redirect from the specific name to the briefer name',
value: 'R from name and country'
},
{
label: '{{R from alternative language}}: redirect from an English name to a name in another language, or vice-versa',
value: 'R from alternative language'
},
{
label: '{{R from ASCII}}: redirect from a title in basic ASCII to the formal article title, with differences that are not diacritical marks (accents, umlauts, etc.)',
value: 'R from ASCII'
},
{
label: '{{R from title without diacritics}}: redirect to the article title with diacritical marks (accents, umlauts, etc.)',
value: 'R from title without diacritics'
}
];
Twinkle.tag.administrativeList = [
{
label: '{{R from merge}}: redirect from a merged page in order to preserve its edit history',
value: 'R from merge'
},
{
label: '{{R to disambiguation page}}: redirect to a disambiguation page',
value: 'R to disambiguation page'
},
{
label: '{{R from duplicated article}}: redirect to a similar article in order to preserve its edit history',
value: 'R from duplicated article'
},
{
label: '{{R to decade}}: redirect from a year to the decade article',
value: 'R to decade'
},
{
label: '{{R from shortcut}}: redirect from a Wikipedia shortcut',
value: 'R from shortcut'
},
{
label: '{{R from CamelCase}}: redirect from a CamelCase title',
value: 'R from CamelCase'
},
{
label: '{{R from EXIF}}: redirect of a wikilink created from JPEG EXIF information (i.e. the \"metadata\" section on some image description pages)',
value: 'R from EXIF'
},
{
label: '{{R from school}}: redirect from a school article that had very little information',
value: 'R from school'
}
];
// maintenance tags for FILES start here
Twinkle.tag.file = {};
Twinkle.tag.file.licenseList = [
{ label: '{{Bsr}}: source info consists of bare image URL/generic base URL only', value: 'Bsr' },
{ label: '{{Non-free reduce}}: non-low-resolution fair use image (or too-long audio clip, etc)', value: 'Non-free reduce' },
{ label: '{{Non-free reduced}}: fair use media which has been reduced (old versions need to be deleted)', value: 'Non-free reduced' }
];
Twinkle.tag.file.cleanupList = [
{ label: '{{Artifacts}}: PNG contains residual compression artifacts', value: 'Artifacts' },
{ label: '{{Bad font}}: SVG uses fonts not available on the thumbnail server', value: 'Bad font' },
{ label: '{{Bad format}}: PDF/DOC/... file should be converted to a more useful format', value: 'Bad format' },
{ label: '{{Bad GIF}}: GIF that should be PNG, JPEG, or SVG', value: 'Bad GIF' },
{ label: '{{Bad JPEG}}: JPEG that should be PNG or SVG', value: 'Bad JPEG' },
{ label: '{{Bad trace}}: auto-traced SVG requiring cleanup', value: 'Bad trace' },
{ label: '{{Cleanup image}}: general cleanup', value: 'Cleanup image' },
{ label: '{{Cleanup SVG}}: SVG needing code and/or appearance cleanup', value: 'Cleanup SVG' },
{ label: '{{ClearType}}: image (not screenshot) with ClearType anti-aliasing', value: 'ClearType' },
{ label: '{{Imagewatermark}}: image contains visible or invisible watermarking', value: 'Imagewatermark' },
{ label: '{{NoCoins}}: image using coins to indicate scale', value: 'NoCoins' },
{ label: '{{Overcompressed JPEG}}: JPEG with high levels of artifacts', value: 'Overcompressed JPEG' },
{ label: '{{Opaque}}: opaque background should be transparent', value: 'Opaque' },
{ label: '{{Remove border}}: unneeded border, white space, etc.', value: 'Remove border' },
{ label: '{{Rename media}}: file should be renamed according to the criteria at [[WP:FMV]]', value: 'Rename media' },
{ label: '{{Should be PNG}}: GIF or JPEG should be lossless', value: 'Should be PNG' },
{
label: '{{Should be SVG}}: PNG, GIF or JPEG should be vector graphics', value: 'Should be SVG',
subgroup: {
name: 'svgCategory',
type: 'select',
list: [
{ label: '{{Should be SVG|other}}', value: 'other' },
{ label: '{{Should be SVG|alphabet}}: character images, font examples, etc.', value: 'alphabet' },
{ label: '{{Should be SVG|chemical}}: chemical diagrams, etc.', value: 'chemical' },
{ label: '{{Should be SVG|circuit}}: electronic circuit diagrams, etc.', value: 'circuit' },
{ label: '{{Should be SVG|coat of arms}}: coats of arms', value: 'coat of arms' },
{ label: '{{Should be SVG|diagram}}: diagrams that do not fit any other subcategory', value: 'diagram' },
{ label: '{{Should be SVG|emblem}}: emblems, free/libre logos, insignias, etc.', value: 'emblem' },
{ label: '{{Should be SVG|fair use}}: fair-use images, fair-use logos', value: 'fair use' },
{ label: '{{Should be SVG|flag}}: flags', value: 'flag' },
{ label: '{{Should be SVG|graph}}: visual plots of data', value: 'graph' },
{ label: '{{Should be SVG|logo}}: logos', value: 'logo' },
{ label: '{{Should be SVG|map}}: maps', value: 'map' },
{ label: '{{Should be SVG|music}}: musical scales, notes, etc.', value: 'music' },
{ label: '{{Should be SVG|physical}}: "realistic" images of physical objects, people, etc.', value: 'physical' },
{ label: '{{Should be SVG|symbol}}: miscellaneous symbols, icons, etc.', value: 'symbol' }
]
}
},
{ label: '{{Should be text}}: image should be represented as text, tables, or math markup', value: 'Should be text' }
];
Twinkle.tag.file.qualityList = [
{ label: '{{Image-blownout}}', value: 'Image-blownout' },
{ label: '{{Image-out-of-focus}}', value: 'Image-out-of-focus' },
{ label: '{{Image-Poor-Quality}}', value: 'Image-Poor-Quality' },
{ label: '{{Image-underexposure}}', value: 'Image-underexposure' },
{ label: '{{Low quality chem}}: disputed chemical structures', value: 'Low quality chem' }
];
Twinkle.tag.file.commonsList = [
{ label: '{{Copy to Commons}}: free media that should be copied to Commons', value: 'Copy to Commons' },
{ label: '{{Do not move to Commons}} (PD issue): file is PD in the US but not in country of origin', value: 'Do not move to Commons' },
{ label: '{{Do not move to Commons}} (other reason)', value: 'Do not move to Commons_reason' },
{ label: '{{Keep local}}: request to keep local copy of a Commons file', value: 'Keep local' },
{ label: '{{Now Commons}}: file has been copied to Commons', value: 'subst:ncd' },
{ label: '{{Shadows Commons}}: a different file is present on Commons under the same filename', value: 'Shadows Commons' }
];
Twinkle.tag.file.replacementList = [
{ label: '{{Obsolete}}: improved version available', value: 'Obsolete' },
{ label: '{{Redundant}}: exact duplicate of another file, but not yet orphaned', value: 'Redundant' },
{ label: '{{PNG version available}}', value: 'PNG version available' },
{ label: '{{SVG version available}}', value: 'SVG version available' }
];
// Tags for DRAFT ARTICLES start here
Twinkle.tag.draftList = [
{ label: '{{New unreviewed article}}: mark article for later review', value: 'new unreviewed article' }
];
// Contains those article tags that can be grouped into {{multiple issues}}.
// This list includes synonyms.
Twinkle.tag.groupHash = [
'advert',
'autobiography',
'BLP IMDb refimprove',
'BLP IMDb-only refimprove',
'BLP sources',
'BLP unsourced',
'BLPrefimprove',
'BLPsources',
'BLPunref',
'BLPunreferenced',
'BLPunsourced',
'citation style',
'citations missing',
'cite check',
'citecheck',
'cleanup',
'cleanup-laundry',
'cleanup-link rot',
'cleanup-reorganize',
'cleanup-rewrite',
'cleanup-spam',
'coi',
'COI',
'colloquial',
'confusing',
'context',
'contradict',
'copy edit',
'copyedit',
'criticism section',
'criticisms',
'crystal',
'dead end',
'deadend',
'disputed',
'do-attempt',
'essay',
'essay-like',
'example farm',
'examplefarm',
'expert',
'external links',
'fancruft',
'fanpov',
'fansite',
'fiction',
'game guide',
'gameguide',
'globalize',
'grammar',
'histinfo',
'hoax',
'howto',
'inappropriate person',
'inappropriate tone',
'incomplete',
'intro length',
'intromissing',
'introrewrite',
'intro-toolong',
'intro-tooshort',
'in-universe',
'jargon',
'laundry',
'laundrylists',
'lead missing',
'lead rewrite',
'lead too long',
'lead too short',
'like resume',
'likeresume',
'linkrot',
'long',
'news release',
'newsrelease',
'notability',
'notable',
'npov',
'one source',
'onesource',
'organize',
'original research',
'orphan',
'out of date',
'over detailed',
'peacock',
'plot',
'pov',
'POV',
'pov-check',
'POV-check',
'primary sources',
'primarysources',
'prose',
'quote farm',
'quotefarm',
'recentism',
'refimprove',
'refimproveBLP',
'reorganisation',
'restructure',
'review',
'rewrite',
'sections',
'self-published',
'spam',
'story',
'synthesis',
'technical',
'tone',
'travel guide',
'travelguide',
'trivia',
'unbalanced',
'unencyclopedic',
'unref',
'unrefBLP',
'unreferenced',
'unreferencedBLP',
'unreliable sources',
'unreliable',
'update',
'very long',
'verylong',
'weasel',
'wikify'
];
Twinkle.tag.callbacks = {
main: function( pageobj ) {
var params = pageobj.getCallbackParameters();
var tagRe, tagText = '', summaryText = 'Added';
var tags = [], groupableTags = [];
// Remove tags that become superfluous with this action
var pageText = pageobj.getPageText().replace(/\{\{\s*(New unreviewed article|Userspace draft)\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\}\s*/ig, "");
var i;
if( Twinkle.tag.mode !== 'redirect' ) {
// Check for preexisting tags and separate tags into groupable and non-groupable arrays
for( i = 0; i < params.tags.length; i++ ) {
tagRe = new RegExp( '(\\{\\{' + params.tags[i] + '(\\||\\}\\}))', 'im' );
if( !tagRe.exec( pageText ) ) {
if( Twinkle.tag.groupHash.indexOf(params.tags[i]) !== -1 &&
(params.tags[i] !== 'globalize' || params.globalizeSubcategory === 'globalize' ) &&
(params.tags[i] !== 'notability' || params.notabilitySubcategory === 'none' )) {
// don't add to multipleissues for globalize/notability subcats
groupableTags = groupableTags.concat( params.tags[i] );
} else {
tags = tags.concat( params.tags[i] );
}
} else {
Status.info( 'Info', 'Found {{' + params.tags[i] +
'}} on the article already...excluding' );
}
}
if( params.group && groupableTags.length >= 3 ) {
Status.info( 'Info', 'Grouping supported tags into {{multiple issues}}' );
groupableTags.sort();
tagText += '{{multiple issues';
summaryText += ' {{[[Template:multiple issues|multiple issues]]}} with parameters';
for( i = 0; i < groupableTags.length; i++ ) {
tagText += '|' + groupableTags[i] +
'={{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}';
if( i === (groupableTags.length - 1) ) {
summaryText += ' and';
} else if ( i < (groupableTags.length - 1) && i > 0 ) {
summaryText += ',';
}
summaryText += ' ' + groupableTags[i];
}
tagText += '}}\n';
} else {
tags = tags.concat( groupableTags );
}
} else {
// Check for pre-existing tags
for( i = 0; i < params.tags.length; i++ ) {
tagRe = new RegExp( '(\\{\\{' + params.tags[i] + '(\\||\\}\\}))', 'im' );
if( !tagRe.exec( pageText ) ) {
tags = tags.concat( params.tags[i] );
} else {
Status.info( 'Info', 'Found {{' + params.tags[i] +
'}} on the redirect already...excluding' );
}
}
}
tags.sort();
for( i = 0; i < tags.length; i++ ) {
var currentTag = "";
if( tags[i] === 'uncategorized' || tags[i] === 'catimprove' ) {
pageText += '\n\n{{' + tags[i] +
'|date={{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}}}';
} else {
if( tags[i] === 'globalize' ) {
currentTag += '{{' + params.globalizeSubcategory;
} else {
currentTag += ( Twinkle.tag.mode === 'redirect' ? '\n' : '' ) + '{{' + tags[i];
}
if( tags[i] === 'notability' && params.notabilitySubcategory !== 'none' ) {
currentTag += '|' + params.notabilitySubcategory;
}
// prompt for other parameters, based on the tag
switch( tags[i] ) {
case 'cleanup':
var reason = prompt('You can optionally enter a more specific reason why the article requires cleanup. \n' +
"Just click OK if you don't wish to enter this. To skip the {{cleanup}} tag, click Cancel.", "");
if (reason === null) {
continue;
} else if (reason !== "") {
currentTag += '|reason=' + reason;
}
break;
case 'copypaste':
var url = prompt('Please enter the URL which is believed to be the source of the copy-paste. \n' +
"Just click OK if you don't know. To skip the {{copypaste}} tag, click Cancel.", "");
if (url === null) {
continue;
} else if (url !== "") {
currentTag += '|url=' + url;
}
break;
case 'not English':
var langname = prompt('Please enter the name of the language the article is thought to be written in. \n' +
"Just click OK if you don't know. To skip the {{not English}} tag, click Cancel.", "");
if (langname === null) {
continue;
} else if (langname !== "") {
currentTag += '|1=' + langname;
}
break;
case 'rough translation':
var roughlang = prompt('Please enter the name of the language the article is thought to have been translated from. \n' +
"Just click OK if you don't know. To skip the {{rough translation}} tag, click Cancel.", "");
if (roughlang === null) {
continue;
} else if (roughlang !== "") {
currentTag += '|1=' + roughlang;
}
break;
case 'expert-subject':
var wikiproject = prompt('Please enter the name of a WikiProject which might be able to help recruit an expert. \n' +
"Just click OK if you don't know. To skip the {{expert-subject}} tag, click Cancel.", "");
if (wikiproject === null) {
continue;
} else if (wikiproject !== "") {
currentTag += '|1=' + wikiproject;
}
break;
case 'merge':
case 'merge to':
case 'merge from':
var param = prompt('Please enter the name of the other article(s) involved in the merge. \n' +
"To specify multiple articles, separate them with a vertical pipe (|) character. \n" +
"This information is required. Click OK when done, or click Cancel to skip the merge tag.", "");
if (param === null) {
continue;
} else if (param !== "") {
currentTag += '|' + param;
}
break;
default:
break;
}
currentTag += Twinkle.tag.mode === 'redirect' ? '}}' : '|date={{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}}}\n';
tagText += currentTag;
}
if ( i > 0 || groupableTags.length > 3 ) {
if( i === (tags.length - 1) ) {
summaryText += ' and';
} else if ( i < (tags.length - 1) ) {
summaryText += ',';
}
}
summaryText += ' {{[[Template:';
if( tags[i] === 'globalize' ) {
summaryText += params.globalizeSubcategory + '|' + params.globalizeSubcategory;
} else {
summaryText += tags[i] + '|' + tags[i];
}
summaryText += ']]}}';
}
if( Twinkle.tag.mode === 'redirect' ) {
pageText += tagText;
} else {
// smartly insert the new tags after any hatnotes. Regex is a bit more
// complicated than it'd need to be, to allow templates as parameters,
// and to handle whitespace properly.
pageText = pageText.replace(/^\s*(?:((?:\s*\{\{\s*(?:about|correct title|dablink|distinguish|for|other\s?(?:hurricaneuses|people|persons|places|uses(?:of)?)|redirect(?:-acronym)?|see\s?(?:also|wiktionary)|selfref|the)\d*\s*(\|(?:\{\{[^{}]*\}\}|[^{}])*)?\}\})+(?:\s*\n)?)\s*)?/i,
"$1" + tagText);
}
summaryText += ' tag' + ( ( tags.length + ( groupableTags.length > 3 ? 1 : 0 ) ) > 1 ? 's' : '' ) +
' to ' + Twinkle.tag.mode + Twinkle.getPref('summaryAd');
pageobj.setPageText(pageText);
pageobj.setEditSummary(summaryText);
pageobj.setWatchlist(Twinkle.getFriendlyPref('watchTaggedPages'));
pageobj.setMinorEdit(Twinkle.getFriendlyPref('markTaggedPagesAsMinor'));
pageobj.setCreateOption('nocreate');
pageobj.save();
if( Twinkle.getFriendlyPref('markTaggedPagesAsPatrolled') ) {
pageobj.patrol();
}
},
file: function friendlytagCallbacksFile(pageobj) {
var text = pageobj.getPageText();
var params = pageobj.getCallbackParameters();
var summary = "Adding ";
// Add in maintenance tags
if (params.tags.length) {
var tagtext = "";
$.each(params.tags, function(k, tag) {
tagtext += "{{" + (tag === "Do not move to Commons_reason" ? "Do not move to Commons" : tag);
var input;
switch (tag) {
case "subst:ncd":