Add translators to the credits dialog

- Add tooling at //tools/i18n to generate the file with the information
  about the translators: //src/json/i18n-credits.json.
- Change credits.json to remove an entry from a translator, who is now
  mentioned in the i18n credits.
- Change Makefile and release.bash to incorporate the i18n credit
  generation in the process of building the extension.
- Change options page to accommodate the translators section.

Change-Id: I7f3991f9c456c381832f4a7bebdfc5581ef9e4be
diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json
index 3ba9d52..433fd17 100644
--- a/src/_locales/en/messages.json
+++ b/src/_locales/en/messages.json
@@ -85,6 +85,14 @@
 		"message": "by",
 		"description": "Fragment of the author statement in an item of the credits. NOTE: put in in lowercase letters. EXAMPLE: '{{options_credits_by}} Adrià Vilanova Martínez'"
 	},
+  "options_credits_translations": {
+    "message": "Translations",
+    "description": "Header for the section in the credits dialog which recognizes translators."
+  },
+  "options_credits_translations_paragraph": {
+    "message": "I would like to give a very special thank you to the following contributors, who have selflessly translated the extension interface to many languages:",
+    "description": "Paragraph in the 'Translations' section of the credits dialog, which recognizes translators. Following this paragraph there's a list with all the translators' names (if you've translated a string in Crowdin, you'll automatically be added to the list in the following extension update)."
+  },
 	"options_ok": {
 		"message": "OK",
 		"description": "OK button in the dialogs"
diff --git a/src/css/options.css b/src/css/options.css
index 7808e30..9aa7b75 100644
--- a/src/css/options.css
+++ b/src/css/options.css
@@ -104,7 +104,7 @@
   width: 100%;
 }
 
-dialog .action_buttons {
+dialog#languages_add_dialog .action_buttons {
   margin-top: 10px;
   float: right;
 }
@@ -140,6 +140,7 @@
   left: 50%;
   margin-left: -216px;
   margin-top: -231px;
+  padding: 0;
   height: 430px;
   width: 400px;
   border: 1px solid rgba(0, 0, 0, 0.3);
@@ -147,25 +148,49 @@
   box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
 }
 
+dialog#credits_dialog[open] {
+  display: flex;
+  flex-direction: column;
+}
+
+dialog#credits_dialog .scrollable {
+  padding: 1em;
+  overflow-y: auto;
+}
+
 dialog#credits_dialog .content_area h4 {
   margin-bottom: 0px;
 }
 
-dialog#credits_dialog .content_area a.homepage {
+dialog#credits_dialog .entry {
+  position: relative;
+}
+
+dialog#credits_dialog .entry a.homepage {
   position: absolute;
   right: 16px;
   font-size: 14px;
 }
 
-dialog#credits_dialog .content_area p,
-dialog#credits_dialog .content_area span {
+dialog#credits_dialog p,
+dialog#credits_dialog span {
   font-size: 14px;
 }
 
-dialog#credits_dialog .content_area p.author {
+dialog#credits_dialog p.author {
   margin-top: 7px;
 }
 
+dialog#credits_dialog #translators .name {
+  font-weight: bold;
+}
+
+dialog .action_buttons {
+  border-top: 1px solid #ccc;
+  padding: 1em;
+  text-align: right;
+}
+
 #otheroptions p {
   margin-top: 0;
   margin-bottom: 0;
diff --git a/src/js/options.js b/src/js/options.js
index a639c56..ca66004 100644
--- a/src/js/options.js
+++ b/src/js/options.js
@@ -129,12 +129,17 @@
     });
 
     // About credits...
-    fetch('json/credits.json')
-        .then(res => res.json())
-        .then(json => {
+    var normalCredits = fetch('json/credits.json').then(res => res.json());
+    var i18nCredits = fetch('json/i18n-credits.json').then(res => res.json());
+
+    Promise.all([normalCredits, i18nCredits])
+        .then(values => {
+          var credits = values[0];
+          var i18nCredits = values[1];
           var content = $('dialog#credits_dialog .content_area');
-          json.forEach(item => {
+          credits.forEach(item => {
             var div = document.createElement('div');
+            div.classList.add('entry');
             if (item.url) {
               var a = document.createElement('a');
               a.classList.add('homepage');
@@ -160,9 +165,35 @@
             content.append(div);
           });
 
+          var cList = document.getElementById('translators');
+          i18nCredits.forEach(contributor => {
+            var li = document.createElement('li');
+            var languages = [];
+            if (contributor.languages) {
+              contributor.languages.forEach(lang => {
+                languages.push(lang.name || 'undefined');
+              });
+            }
+
+            var name = document.createElement('span');
+            name.classList.add('name');
+            name.textContent = contributor.name || 'undefined';
+            li.append(name);
+
+            if (languages.length > 0) {
+              var languages =
+                  document.createTextNode(': ' + languages.join(', '));
+              li.append(languages);
+            }
+
+            cList.append(li);
+          });
+
           window.onhashchange = function() {
             if (location.hash == '#credits') {
-              $('dialog#credits_dialog').showModal();
+              var credits = document.getElementById('credits_dialog');
+              credits.showModal();
+              credits.querySelector('.scrollable').scrollTo(0, 0);
               $('#credits_ok').focus();
             }
           };
diff --git a/src/json/credits.json b/src/json/credits.json
index 9e8243e..690e2a6 100644
--- a/src/json/credits.json
+++ b/src/json/credits.json
@@ -5,11 +5,6 @@
     "author": "dAKirby309"
   },
   {
-    "name": "Russian Translation",
-    "url": "https://code.google.com/r/sashasimkin-translateselectedtext/source/detail?r=fc4e58ee0d69929d610a84a7600338e99b9d3d83",
-    "author": "Alexander Simkin"
-  },
-  {
     "name": "Sortable",
     "url": "https://github.com/RubaXa/Sortable",
     "author": "Lebedev Konstantin",
diff --git a/src/options.html b/src/options.html
index 2765d1a..ade625c 100644
--- a/src/options.html
+++ b/src/options.html
@@ -46,8 +46,18 @@
     </div>
   </dialog>
   <dialog id="credits_dialog">
-    <h3 data-i18n="credits"></h3>
-    <div class="content_area">
+    <div class="scrollable">
+      <h3 data-i18n="credits"></h3>
+      <div class="entry">
+        <a href="https://gtranslate.avm99963.com/" class="homepage" target="_blank" data-i18n="credits_homepage"></a>
+        <h4 data-i18n="credits_translations"></h4>
+        <div data-i18n="credits_translations_paragraph">
+        </div>
+        <ul id="translators">
+        </ul>
+      </div>
+      <div class="content_area">
+      </div>
     </div>
     <div class="action_buttons">
       <button id="credits_ok" data-i18n="ok"></button>