User talk:Jack Phoenix/archive 4

GoogleTrans gadget now recoded
Hi there,

Last year you mentioned to me in a post that you had looked at my GoogleTrans gadget and it was old and ugly code that you wouldn't work with.

This is to alert you that I have recoded quite a bit of the gadget now. It is a Javascript Object now, the code to determine the word under the cursor, and whether the cursor is in the selected text has been completely rewritten.

Endo999 (talk) 19:36, 22 December 2016 (UTC)


 * Hey Endo999, glad to hear that!


 * I took a look at the code and while it's clearly an improved version over the previous one, there are still some things to fix. JSHint, the JavaScript code quality tool used for MediaWiki core and many MediaWiki extension, produces the following errors about the current version of the code (161 erros in total):

Line 10, column 16: The object literal notation {} is preferable. GT = new Object;

Line 157, column 50: Missing semicolon. if (s.styleSheet) s.styleSheet.cssText = text //IE

Line 158, column 59: Missing semicolon. else s.appendChild(document.createTextNode(text + '')) //Safari sometimes borks on null

Line 210, column 39: The Function constructor is a form of eval. span1.onMouseover=new Function("return GT.SCdonthide=true;");

Line 259, column 2: Missing semicolon. }

Line 263, column 2: Missing semicolon. }

Line 307, column 16: Use '===' to compare with 'null'. if(retCookie == null || retCookie == "undefined")

Line 319, column 7: Bad line breaking before '&&'. && (bIsOn == "0" || bIsOn == ""))

Line 319, column 33: Use '===' to compare with ''. && (bIsOn == "0" || bIsOn == ""))

Line 343, column 7: Implied eval. Consider passing a function instead of a string. setTimeout("GT.SCTextSettings",1000);

Line 425, column 29: Missing semicolon. GT.SCIsTextToSpeechOn = true

Line 445, column 57: Missing semicolon. "http://translate.google.com/translate_tts?tl=en&amp;q="

Line 548, column 9: Expected an assignment or function call and instead saw an expression. GT.i;

Line 593, column 6: Bad line breaking before '='. = function {

Line 980, column 11: Bad line breaking before '=='. == lcode.toLowerCase )

Line 1113, column 43: Expected an assignment or function call and instead saw an expression. GT.SCscreenWidth = 0, GT.SCscreenHeight = 0;

Line 1114, column 33: Expected an assignment or function call and instead saw an expression. GT.SCwrheight=250, GT.SCwrwidth=300;

Line 1115, column 32: Expected an assignment or function call and instead saw an expression. GT.SCscrOfX = 0, GT.SCscrOfY = 0;

Line 1116, column 33: Expected an assignment or function call and instead saw an expression. GT.SCWikihtml="", GT.SCDicthtml="";

Line 1144, column 32: The array literal notation [] is preferable. GT.SCselectionarray = new Array;

Line 1145, column 32: The array literal notation [] is preferable. GT.SCselectionstart = new Array;

Line 1146, column 30: The array literal notation [] is preferable. GT.SCselectionend = new Array;

Line 1147, column 40: The array literal notation [] is preferable. GT.SCselectionarrayposition = new Array;

Line 1148, column 27: The array literal notation [] is preferable. GT.SCselection = new Array;

Line 1162, column 4: Expected an assignment or function call and instead saw an expression. GT.SCIeRange;

Line 1163, column 4: Expected an assignment or function call and instead saw an expression. GT.SCSelectionType;

Line 1223, column 8: Value of 'e' may be overwritten in IE 8 and earlier. catch(e)

Line 1263, column 30: Use '===' to compare with 'true'. if (evt.altKey==1||evt.altKey==true)

Line 1267, column 16: Use '===' to compare with 'true'. if(evt.ctrlKey ==true && GT.SCAltKey==true && GT.SCbInTranslationFeaturePage && window.getSelection && window.getSelection.toString != "")

Line 1267, column 37: Use '===' to compare with 'true'. if(evt.ctrlKey ==true && GT.SCAltKey==true && GT.SCbInTranslationFeaturePage && window.getSelection && window.getSelection.toString != "")

Line 1267, column 137: Use '!==' to compare with ''. if(evt.ctrlKey ==true && GT.SCAltKey==true && GT.SCbInTranslationFeaturePage && window.getSelection && window.getSelection.toString != "")

Line 1292, column 35: Use '===' to compare with 'true'. if ((evt.shiftKey==1||evt.shiftKey==true) ||

Line 1318, column 8: Value of 'e' may be overwritten in IE 8 and earlier. catch(e)

Line 1327, column 30: Use '===' to compare with 'false'. if(key == 27 && this.SCdebug == false) // escape key

Line 1332, column 35: Use '===' to compare with 'true'. else if(key == 27 && this.SCdebug == true)

Line 1461, column 39: Missing semicolon. GTSCrangeOffset = evt.rangeOffset

Line 1479, column 54: Use '===' to compare with 'false'. if(/*mouseClick == 1 &&*/ this.SCbIsOutsideClientArea==false)

Line 1511, column 13: Bad line breaking before '+'. + document.documentElement.scrollLeft;

Line 1513, column 13: Bad line breaking before '+'. + document.documentElement.scrollTop;

Line 1581, column 19: Use '===' to compare with 'null'. if(sel == null ||sel.toString == "" )

Line 1581, column 44: Use '===' to compare with ''. if(sel == null ||sel.toString == "" )

Line 1583, column 35: Use '!==' to compare with ''. else if(sel.toString != "")

Line 1701, column 42: Missing semicolon. bLeftElementHoldsCursor = true

Line 1705, column 43: Missing semicolon. bRightElementHoldsCursor = true

Line 1719, column 22: Missing semicolon. oFound = o1

Line 1730, column 19: 'mid' is already defined. var mid = Math.floor(o2.innerText.length/2);

Line 1734, column 22: Missing semicolon. oFound = o2

Line 1758, column 49: This character may get silently deleted by one or more browsers. if(textobj.nodeValue.substr(i,1).match(/[\sã€ã€‚ï¼Œ]/))

Line 1760, column 47: This character may get silently deleted by one or more browsers. if(textobj.nodeValue.substr(i,1).match(/[\sã€ã€‚ï¼Œ]/))

Line 1766, column 59: This character may get silently deleted by one or more browsers. if(textobj.nodeValue.substr(beginword+i,1).match(/[\sã€ã€‚ï¼Œ]/))

Line 1817, column 43: Use '===' to compare with 'null'. if(window.getSelection.toString == null || window.getSelection.toString=="")

Line 1817, column 86: Use '===' to compare with ''. if(window.getSelection.toString == null || window.getSelection.toString=="")

Line 1841, column 20: 'selection' is already defined. var selection = window.getSelection;

Line 1843, column 16: 'range' is already defined. var range = document.createRange;

Line 1960, column 44: Missing semicolon. "Wikipedialanguage")

Line 1992, column 7: Bad line breaking before '&&'. && ((this.SCsrcElement.getAttribute("title") != null &&

Line 1992, column 52: Use '!==' to compare with 'null'. && ((this.SCsrcElement.getAttribute("title") != null &&

Line 1993, column 51: Use '!==' to compare with ''. this.SCsrcElement.getAttribute("title") != "")

Line 1994, column 11: Bad line breaking before '||'. ||

Line 2004, column 7: Bad line breaking before '&&'. && ((Elem.getAttribute("title") != null &&

Line 2004, column 39: Use '!==' to compare with 'null'. && ((Elem.getAttribute("title") != null &&

Line 2005, column 38: Use '!==' to compare with ''. Elem.getAttribute("title") != "")

Line 2006, column 11: Bad line breaking before '||'. ||

Line 2159, column 38: Missing semicolon. curleft += obj.offsetLeft

Line 2180, column 36: Missing semicolon. curtop += obj.offsetTop

Line 2265, column 21: Bad line breaking before '&&'. && !this.SCdontposition

Line 2291, column 7: Bad line breaking before '&&'. && typeof this.SCtranslateTo != "undefined"

Line 2303, column 34: Use '!==' to compare with ''. if(persistantlanguagepathFrom != "" &&

Line 2304, column 32: Use '!==' to compare with ''. persistantlanguagepathTo != "")

Line 2338, column 29: Missing semicolon. newspan.innerHTML = newhtml

Line 2502, column 27: Use '===' to compare with ''. if(persistantlanguageFrom == "")

Line 2505, column 25: Use '===' to compare with ''. if(persistantlanguageTo == "")

Line 2532, column 1: Bad line breaking before '+'. +' ' +

Line 2563, column 70: Script URL. newspan.setAttribute("onMouseover","javascript:GT.SCdonthide=true;");

Line 2566, column 40: The Function constructor is a form of eval. newspan.onmouseover = new Function("GT.SCdonthide=true;");

Line 2589, column 28: Use '!==' to compare with ''. if(this.SCtextareatext != "" &&

Line 2594, column 17: 'obj' is already defined. var obj = document.getElementById("languageoptionsFrom");

Line 2611, column 22: Use '===' to compare with ''. if(defaultlanguage == "")

Line 2652, column 32: Use '!==' to compare with ''. if(parobj && this.SCWikihtml != "")

Line 2667, column 44: Missing semicolon. "Wikipedialanguage")

Line 2679, column 32: Use '!==' to compare with ''. if(parobj && this.SCDicthtml != "")

Line 2690, column 30: Use '===' to compare with ''. if(this.SCtranslateFrom == "")

Line 2692, column 28: Use '===' to compare with ''. if(this.SCtranslateTo == "")

Line 2754, column 7: Bad line breaking before '||'. || this.SCtranslateFrom == "ja"

Line 2756, column 8: Bad line breaking before '||'. ||

Line 2768, column 24: Use '!==' to compare with 'null'. for(i=wordindex;words!= null && i<=wordindexend;i++)

Line 2888, column 5: Bad line breaking before '&&'. && this.SCposx <= rightt

Line 2889, column 5: Bad line breaking before '&&'. && this.SCposy >= topp

Line 2890, column 5: Bad line breaking before '&&'. && this.SCposy <= bottomm

Line 2897, column 8: Bad line breaking before '+'. + ":" + rightt + ":" +

Line 2901, column 9: Bad line breaking before '+'. +bottomm+":"+":"

Line 2902, column 10: Bad line breaking before '+'. +document.body.scrollTop+":" +

Line 2904, column 8: Bad line breaking before '+'. +this.SCposx+":"+this.SCposy);

Line 2951, column 10: Use '===' to compare with ''. if(str == "")

Line 2953, column 21: This character may get silently deleted by one or more browsers. if(str.match(/^[-ã€ï¼Œã€‚ã€‹ã€Šã€ã€Œï¼šï¼ˆï¼‰ã€”ã€•Â·ï¼Ÿ%]/))

Line 3068, column 72: Missing semicolon. this.audiooff(ob.childNodes[0].childNodes[0],true)

Line 3102, column 26: Do not use Number as a constructor. this.SCthewordspeed= (new Number(this.SCthewordspeed)) +5;

Line 3115, column 26: Do not use Number as a constructor. this.SCthewordspeed =(new Number(this.SCthewordspeed))-5;

Line 3188, column 12: Use '===' to compare with 'null'. if(sel == null )

Line 3207, column 39: The array literal notation [] is preferable. this.SCTextElementArray= new Array;

Line 3208, column 46: The array literal notation [] is preferable. this.SCTextElementLengthArray = new Array;

Line 3235, column 18: Use '!==' to compare with ''. while((nextchar != "" && !nextchar.match(re1))||sentencelength < minsentencelength)

Line 3245, column 12: Use '===' to compare with '0'. if(1==0&& nextchar.match(/./))

Line 3291, column 18: 'debug' is already defined. var debug = false;

Line 3312, column 18: 'debug' is already defined. var debug=false;

Line 3327, column 8: Expected an assignment or function call and instead saw an expression. GT.SCselnode;

Line 3328, column 8: Expected an assignment or function call and instead saw an expression. GT.SCseloffset;

Line 3329, column 8: Expected an assignment or function call and instead saw an expression. GT.SCselnodeend;

Line 3330, column 8: Expected an assignment or function call and instead saw an expression. GT.SCseloffsetend;

Line 3332, column 7: Expected an assignment or function call and instead saw an expression. GT.SCselnodeend1;

Line 3333, column 8: Expected an assignment or function call and instead saw an expression. GT.SCseloffsetend1;

Line 3339, column 33: The array literal notation [] is preferable. GT.SCTextElementArray= new Array;

Line 3340, column 40: The array literal notation [] is preferable. GT.SCTextElementLengthArray = new Array;

Line 3368, column 22: Use '!==' to compare with ''. if(rangeset != "")

Line 3386, column 27: Use '!==' to compare with 'null'. if(nextsibling != null)

Line 3396, column 26: Use '!==' to compare with ''. if(rangeset != "")

Line 3405, column 18: Bad line breaking before '&&'. && typeof type != "undefined" &&

Line 3417, column 18: Bad line breaking before '&&'. && typeof type != "undefined" &&

Line 3434, column 26: Use '!==' to compare with ''. if(rangeset != "")

Line 3443, column 29: Use '===' to compare with '0'. if(this.SCseloffsetend==0)

Line 3449, column 69: Missing semicolon. this.SCffrange.setEnd(this.SCselnodeend,++this.SCseloffsetend)

Line 3651, column 18: 'retstr' is already defined. var retstr = response.text[i];

Line 3693, column 18: 'retstr' is already defined. var retstr = response.data.translations[i].translatedText;

Line 3822, column 60: Use '===' to compare with '0'. if(response.data && response.data.translations && 1==0)

Line 3948, column 7: 'i' is already defined. var i=0,j=0;

Line 3954, column 15: Use '===' to compare with ''. if(lcode=="")

Line 4044, column 101: Use '===' to compare with '0'. if(result.error && this.SCIsTransliteratable(this.SCtranslateTo,this.SCtranslateFrom && 1==0))

Line 4057, column 31: Use '!==' to compare with ''. if(this.SCtextareatext != "" &&

Line 4095, column 7: Bad line breaking before '+'. + ' '

Line 4102, column 37: Use '!==' to compare with ''. if(this.SCtextareatext!= "")

Line 4135, column 31: Use '!==' to compare with ''. if(this.SCtextareatext != "" &&

Line 4149, column 15: Use '!==' to compare with ''. ((texta != "")?texta:result.error.message) + " ";

Line 4152, column 37: Use '!==' to compare with ''. if(this.SCtextareatext!= "")

Line 4170, column 7: Bad line breaking before '&&'. && typeof this.SCtranslateTo != "undefined"

Line 4182, column 34: Use '!==' to compare with ''. if(persistantlanguagepathFrom != "" &&

Line 4183, column 32: Use '!==' to compare with ''. persistantlanguagepathTo != "")

Line 4255, column 18: Do not use Number as a constructor. var version1 = new Number(RegExp.$1);

Line 4284, column 46: Use '===' to compare with 'true'. this.SCPersistantLoad('GoogleTrans') == true)

Line 4321, column 19: 'version1' is already defined. var version1 = new Number(RegExp.$1);

Line 4321, column 21: Do not use Number as a constructor. var version1 = new Number(RegExp.$1);

Line 4355, column 19: 'version1' is already defined. var version1 = new Number(RegExp.$1);

Line 4355, column 21: Do not use Number as a constructor. var version1 = new Number(RegExp.$1);

Line 4356, column 21: Do not use Number as a constructor. var version2 = new Number(RegExp.$2);

Line 4382, column 19: 'version1' is already defined. var version1 = new Number(RegExp.$1);

Line 4382, column 21: Do not use Number as a constructor. var version1 = new Number(RegExp.$1);

Line 4383, column 19: 'version2' is already defined. var version2 = new Number(RegExp.$2);

Line 4383, column 21: Do not use Number as a constructor. var version2 = new Number(RegExp.$2);

Line 4398, column 16: 'version1' is already defined. var version1 = new Number(RegExp.$1);

Line 4398, column 18: Do not use Number as a constructor. var version1 = new Number(RegExp.$1);

Line 4430, column 27: Use '!==' to compare with ''. if(this.SCpersistlangFrom != "")

Line 4434, column 25: Use '!==' to compare with ''. if(this.SCpersistlangTo != "")

Line 4438, column 20: Use '!==' to compare with ''. if(this.SCwikilang != "")

Line 4444, column 16: 'version1' is already defined. var version1 = new Number(RegExp.$1);

Line 4444, column 18: Do not use Number as a constructor. var version1 = new Number(RegExp.$1);

Line 4526, column 1: Bad line breaking before '+'. +

Line 4543, column 1: Implied eval. Consider passing a function instead of a string. setInterval("GT.SCinterval",1000);

Line 4557, column 34: Use '===' to compare with ''. if(bPops == "1" || bPops == "")

Line 4561, column 21: Use '===' to compare with ''. if(bPops == "")

Line 4571, column 73: Script URL. mw.util.addPortletLink('p-cactions',"javascript:GT.SCSettings", title, "ca-TransPopsId", GT.SCstrChangeOptions, "");

Line 1, column 20: Missing semicolon. GT.SCTextSettings

Line 1, column 16: Missing semicolon. GT.SCinterval


 * A few of these might be invalid or subjective (mostly the "bad line breaking" ones), but a lot of them appear to be valid. Additionally you might want to familiarize yourself with MediaWiki's JavaScript coding conventions &mdash; while they, too, are somewhat subjective, they're widely accepted in the MediaWiki developer community and for a good reason.


 * Some additional thoughts:


 * Do you really need to explicitly check for certain browsers (e.g. Konqueror, Netscape)? As per Compatibility, only certain modern browsers receive Grade A support. JavaScript isn't even loaded for certain ancient browsers (IE6 & 7 at least) anymore, so chances are your code will never be executed in these browsers anymore.
 * You may want to use  or   (I think the latter one is the recommended one) ResourceLoader module instead for the cookie stuff instead of rolling out your own logic.
 * Finding X and Y position can likely be done via jQuery. jQuery is one of those few things always guaranteed to be available in the MediaWiki environment (but some specific jQuery plugins, such as the aforementioned cookie-related ones, are not always available and have to be explicitly loaded). --Jack Phoenix (Contact) 17:00, 7 January 2017 (UTC)

I've had a look at your error listing, and made changes to the code to reduce the number of LINT errors. I tried out JSINT and it is too finicky to actually use. But I will try to get the style better than it was before.

Endo999 (talk) 04:23, 13 January 2017 (UTC)


 * I finally got JSHINT to work in my Notepad++ and allowed for "tolerate messy white space". I only have 6 errors now, most of which have to do with nonascii characters in regular expressions.  (I'm going to keep these because they make GoogleTrans work with Chinese/Japanese characters).  Thanks for telling me about JSHINT.  I will definitely run javascript through it in the future.  I've updated the gadget source file with the JSHINTed javascript source.  Endo999 (talk) 07:02, 19 January 2017 (UTC)

WikiIndex eMail
Have You ever tried to get Your email verified after we solved the email-problem on WikiIndex? -- Manorainjan  17:49, 15 February 2017 (UTC)


 * My email has been confirmed on WikiIndex since early March 2009, so I'm not sure what you're referring to, but it's probably a more recent issue, so I haven't experienced it. --Jack Phoenix (Contact) 08:37, 20 February 2017 (UTC)

Social Tools Integration with Flow
Hi, Would any of the Social Tools extension work with Flow extension? For example WikiForum, VoteNY? I could not find Flow compatibility infomration anywhere. I missed it, would appreciate a pointer.

Thanks, TitusiMW


 * There is no explicit support for Flow. But fear not, like Extension:LiquidThreads, Flow is DOA. It hasn't been actively developed since October 2015 and it was disabled on the English Wikipedia in November 2016. --Jack Phoenix (Contact) 11:30, 1 March 2017 (UTC)

Request to delete my own user page
Hi! I didn't find administrators' noticeboard in MediaWiki so I decided to contact some admin on his / her talk page. I'd like to delete my own user page on MediaWiki. Could you please do it? --Smaug the Golden (talk - contributions - logs) 18:49, 4 March 2017 (UTC)

Statcounter
Please tell me where to change the variables for statcounter extension!

Extension:QuizGame - where is the documentation?
Hello! I asked this on the extension's talk page over a week ago, with no reply. I see you're listed as a developer of the extension, so I'm hoping you can help me.

I don't see any links to documentation for QuizGame anywhere on the extension's description page. Especially end-user documentation - how do people write content for this thing? --Robkelk (talk) 21:28, 11 February 2018 (UTC)

I have a problem during use WikiForm 2.5
Hi,Jack!

I'm glad to find the WikiForum,and used it on my website. But I found a problem,I've writed it here:

https://phabricator.wikimedia.org/T217989

Please help me.Thanks very much.

--Onlyou408 (talk) 14:15, 21 March 2019 (UTC)Onlyou408.

Regarding integration of Extension:VoteNY and 'Flow'
Hello Jack ! I want to use 'Extension:VoteNY' which you authored. This extension is really smooth and efficient. I am working on a MediaWiki project. You might be aware of the Extension:StructuredDiscussions a.k.a 'Flow'. I want to add a voting feature to the user replies in the 'Structured:Discussions', similar to your extension's in which a vote counter appears. I hope it is possible. I wanted to know your opinion in this matter. Can you please guide me sir ?

Regards, Falcopragati (talk) 06:03, 21 June 2019 (UTC) Pragati Sharma

Bug in Extension:LinkSuggest
Hi, the extension Extension:LinkSuggest Does something on an unexpected way.

I was writing an article, in "edit source" (not graphic editor or visual editor).

And the things happened this way:


 * I was typing a link, and the "suggested links" pop-up appeared
 * I Click with the cursor on a few lines after that
 * I use the mouse wheel
 * I choose a name from some of the suggested ones
 * BUG— The text is deleted as far as my cursor is

I would like it very much if this bug could be fixed, as this extension is otherwise very helpful and we had to disable it because of this error

The bug is very easy to reproduce, so i'm open to questions. Also i have pics of the before and after of one of these issues with the Extension:LinkSuggest.


 * https://cdn.discordapp.com/attachments/371992308100628491/730873119996117022/Linksuggest_01.png
 * https://cdn.discordapp.com/attachments/371992308100628491/730873168872341576/Linksuggest_02.png
 * https://cdn.discordapp.com/attachments/371992308100628491/730873257355509830/Linksuggest_03.png

Best regards, --Paladium (talk) 20:09, 9 July 2020 (UTC)


 * Bugs are best reported on Phabricator to ensure that other developers will also see the issue (see how to report a bug for more details etc.). That said, maybe Ciencia Al Poder, as the primary author of that extension's JS part, has some idea as to what's going on in here and how to fix it? --Jack Phoenix (Contact) 11:04, 22 July 2020 (UTC)

Comments Extension stopped working
As of MW1.34 the comments extension stopped working (This version cannot work). I have just confirmed it doesn't work with MW1.36 either. This also means part of the Social Profile things won't work either, since they require the Comments extension to be installed in order to work.

BTW, this was already listed in April 2020, so it's been over a year since it's been noticed and confirmed for the first time that it doesn't work anymore.

I hope it can be fixed soon!

IlseMul (talk) 12:09, 10 August 2021 (UTC)


 * I've tested Comments (and other social tools and the non-social tools extensions and skins I maintain) extensively under MW 1.35.x and it seems to be working fine. As per Social tools/MediaWiki compatibility, amended this July, compatibility with the mentioned non-1.35 versions is incidental more than intentional...although to be honest, I don't really see how the MW version in use, whether 1.34, 1.35 or 1.36, would affect the mentioned things. That said, I've not been able to reproduce the problem in question nor have there been multiple new reports about it, so I'm not able to action on it or suggest anything else than maybe doing a fresh checkout, ensuring you use a tested, "officially supported" MW version (i.e. 1.35.x). Run update.php again and see what happens. --Jack Phoenix (Contact) 15:42, 10 August 2021 (UTC)

Add Social Media+ tab in Social Profiles
Hi Jack,

Seen that Social Profile is a Social tool, I was thinking it would be good to have social media links as a default option/tab in the Social Profile. Currently there's only "websites" under personal information, but a tab called Social Media+ or something like Other ways to contact me or something could be handy with links to:
 * Facebook
 * Twitter
 * LinkedIn
 * Instagram
 * DeviantArt
 * ArtStation
 * Personal Website/Blog
 * Professional website
 * Other?

I'm making a Wiki where game Developers can post as well and this information can come in very handy.

Thanks for the consideration!

IlseMul (talk) 11:55, 10 August 2021 (UTC)

You definitely should post this feature request on Phabricator to ensure it gets properly tracked! (It's an interesting idea but sadly I'm unable to promise you definitely, "yes, this will get implemented by " as I'm swamped with all kinds of projects, online and offline alike. But it's why we have Phabricator, to track bugs and feature requests and to enable all interested people to read about them and to work on them!) --Jack Phoenix (Contact) 15:42, 10 August 2021 (UTC)
 * This seems like a great idea! It'll require a bit of UI consideration, given the wide variety of social media sites and whatnot, but certainly is something we should do. I presume the only reason it hasn't been done and wasn't done by the original developers is that social tools predate sites like Instagram by years, and even giants like Facebook or Twitter which were a thing back then weren't anywhere as big as they are nowadays. :-)