Display additional information in VK profile

Display profile ID, registration date, last profile edit and last seen in VK user profile

当前为 2019-01-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Display additional information in VK profile
  3. // @name:ru Отображение доп. информации на странице ВКонтакте
  4. // @name:uk Відображення доп. інформації на сторінці VK
  5. // @namespace https://greasyfork.org/ru/users/155145-inlifeuser
  6. // @version 2019.01.25
  7. // @description Display profile ID, registration date, last profile edit and last seen in VK user profile
  8. // @description:ru Отображение номера страницы (ID), даты регистрации, последнего редактирования страницы и последний заход на странице пользователя ВКонтакте
  9. // @description:uk Відображення номера сторінки (ID), дати реєстрації, останнього редагування сторінки і останній візит на сторінці користувача VK
  10. // @author Inlifeuser
  11. // @license MIT
  12. // @include *://vk.com/*
  13. // @exclude *://vk.com/notifier.php*
  14. // @exclude *://vk.com/*widget*.php*
  15. // @run-at document-end
  16. // ==/UserScript==
  17.  
  18. 'use strict';
  19. function addLeadingZeroToDate (date) {
  20. return ('0' + date).slice(-2);
  21. }
  22. function convert24HoursTo12Hours (hours) {
  23. hours = hours % 12;
  24. return hours ? hours : 12;
  25. }
  26. function convert24HoursToAmPmLc (hours) {
  27. return hours >= 12 ? 'pm' : 'am';
  28. }
  29. (function () {
  30. new MutationObserver(function () {
  31. var vkProfilePage = document.body.querySelector('#profile_short:not(.display_additional_information_in_vk_profile)');
  32. if (!vkProfilePage) return;
  33. var vkAbuseButton = document.body.querySelector('a.page_actions_item[onclick*="abuse"]');
  34. var vkProfileId;
  35. if (vkAbuseButton) {
  36. vkProfileId = (vkAbuseButton.getAttribute('onclick').match(/oid: (\d+)/i) || [])[1];
  37. } else {
  38. var vkProfileWall = document.body.querySelector('a.ui_tab_sel[href*="/wall"]');
  39. if (!vkProfileWall) return;
  40. vkProfileId = (vkProfileWall.href.match(/wall(\d+)/i) || [])[1];
  41. }
  42. if (!vkProfileId) return;
  43. vkProfilePage.className += ' display_additional_information_in_vk_profile';
  44. var vkPageLang = document.body.querySelector('a.ui_actions_menu_item[onclick*="lang_dialog"]');
  45. var vkCurrentLang;
  46. if (vkPageLang) {
  47. vkCurrentLang = vkPageLang.textContent;
  48. } else {
  49. vkCurrentLang = navigator.language.substring(0, 2);
  50. }
  51. var vkLang, vkMonthName;
  52. if (vkCurrentLang === 'Language: english' || vkCurrentLang === 'en') {
  53. vkLang = 'en';
  54. vkMonthName = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  55. } else if (vkCurrentLang === 'Язык: русский' || vkCurrentLang === 'ru') {
  56. vkLang = 'ru';
  57. vkMonthName = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'];
  58. } else if (vkCurrentLang === 'Мова: українська' || vkCurrentLang === 'uk') {
  59. vkLang = 'uk';
  60. vkMonthName = ['сiчня', 'лютого', 'березня', 'квiтня', 'травня', 'червня', 'липня', 'серпня', 'вересня', 'жовтня', 'листопада', 'грудня'];
  61. }
  62. var i = 0;
  63. while (i < 4) {
  64. var vkProfilePageElement = document.createElement('div');
  65. vkProfilePageElement.style.display = 'none';
  66. vkProfilePage.insertBefore(vkProfilePageElement, vkProfilePage.firstChild);
  67. i++;
  68. }
  69. var vkProfileIdElement = document.createElement('div');
  70. vkProfileIdElement.className = 'clear_fix profile_info_row';
  71. if (vkLang === 'en') {
  72. vkProfileIdElement.innerHTML = '<div class="label fl_l">Profile ID:</div><div class="labeled">' + vkProfileId + '</div>';
  73. } else if (vkLang === 'ru') {
  74. vkProfileIdElement.innerHTML = '<div class="label fl_l">Номер страницы:</div><div class="labeled">' + vkProfileId + '</div>';
  75. } else if (vkLang === 'uk') {
  76. vkProfileIdElement.innerHTML = '<div class="label fl_l">Номер сторінки:</div><div class="labeled">' + vkProfileId + '</div>';
  77. } else {
  78. vkProfileIdElement.innerHTML = '<div class="label fl_l">Profile ID:</div><div class="labeled">' + vkProfileId + '</div>';
  79. }
  80. vkProfilePage.replaceChild(vkProfileIdElement, vkProfilePage.childNodes[0]);
  81. var requestVkFoaf = new XMLHttpRequest();
  82. requestVkFoaf.onreadystatechange = function () {
  83. if (this.readyState === 4 && this.status === 200) {
  84. var vkFoafRegDate = (this.responseText.match(/ya:created dc:date="(.+)"/i) || [])[1];
  85. var vkFoafLastProfileEditDate = (this.responseText.match(/ya:modified dc:date="(.+)"/i) || [])[1];
  86. var vkFoafLastSeenDate = (this.responseText.match(/ya:lastLoggedIn dc:date="(.+)"/i) || [])[1];
  87. if (vkFoafRegDate) {
  88. var vkRegDate = new Date(vkFoafRegDate);
  89. var vkRegDateElement = document.createElement('div');
  90. vkRegDateElement.className = 'clear_fix profile_info_row';
  91. if (vkLang === 'en') {
  92. vkRegDateElement.innerHTML = '<div class="label fl_l">Registration date:</div><div class="labeled">' + vkMonthName[vkRegDate.getMonth()] + ' ' + vkRegDate.getDate() + ', ' + vkRegDate.getFullYear() + ' at ' + convert24HoursTo12Hours(vkRegDate.getHours()) + ':' + addLeadingZeroToDate(vkRegDate.getMinutes()) + ':' + addLeadingZeroToDate(vkRegDate.getSeconds()) + ' ' + convert24HoursToAmPmLc(vkRegDate.getHours()) + '</div>';
  93. } else if (vkLang === 'ru') {
  94. vkRegDateElement.innerHTML = '<div class="label fl_l">Дата регистрации:</div><div class="labeled">' + vkRegDate.getDate() + ' ' + vkMonthName[vkRegDate.getMonth()] + ' ' + vkRegDate.getFullYear() + ' в ' + vkRegDate.getHours() + ':' + addLeadingZeroToDate(vkRegDate.getMinutes()) + ':' + addLeadingZeroToDate(vkRegDate.getSeconds()) + '</div>';
  95. } else if (vkLang === 'uk') {
  96. vkRegDateElement.innerHTML = '<div class="label fl_l">Дата реєстрації:</div><div class="labeled">' + vkRegDate.getDate() + ' ' + vkMonthName[vkRegDate.getMonth()] + ' ' + vkRegDate.getFullYear() + ' о ' + vkRegDate.getHours() + ':' + addLeadingZeroToDate(vkRegDate.getMinutes()) + ':' + addLeadingZeroToDate(vkRegDate.getSeconds()) + '</div>';
  97. } else {
  98. vkRegDateElement.innerHTML = '<div class="label fl_l">Registration date:</div><div class="labeled">' + addLeadingZeroToDate(vkRegDate.getDate()) + '.' + addLeadingZeroToDate(vkRegDate.getMonth() + 1) + '.' + vkRegDate.getFullYear() + ' ' + addLeadingZeroToDate(vkRegDate.getHours()) + ':' + addLeadingZeroToDate(vkRegDate.getMinutes()) + ':' + addLeadingZeroToDate(vkRegDate.getSeconds()) + '</div>';
  99. }
  100. vkProfilePage.replaceChild(vkRegDateElement, vkProfilePage.childNodes[1]);
  101. } else {
  102. console.info('Registration date on VK FOAF profile is empty or unavailable');
  103. }
  104. if (vkFoafLastProfileEditDate) {
  105. var vkLastProfileEditDate = new Date(vkFoafLastProfileEditDate);
  106. var vkLastProfileEditDateElement = document.createElement('div');
  107. vkLastProfileEditDateElement.className = 'clear_fix profile_info_row';
  108. if (vkLang === 'en') {
  109. vkLastProfileEditDateElement.innerHTML = '<div class="label fl_l">Last profile edit:</div><div class="labeled">' + vkMonthName[vkLastProfileEditDate.getMonth()] + ' ' + vkLastProfileEditDate.getDate() + ', ' + vkLastProfileEditDate.getFullYear() + ' at ' + convert24HoursTo12Hours(vkLastProfileEditDate.getHours()) + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getSeconds()) + ' ' + convert24HoursToAmPmLc(vkLastProfileEditDate.getHours()) + '</div>';
  110. } else if (vkLang === 'ru') {
  111. vkLastProfileEditDateElement.innerHTML = '<div class="label fl_l">Посл. ред. страницы:</div><div class="labeled">' + vkLastProfileEditDate.getDate() + ' ' + vkMonthName[vkLastProfileEditDate.getMonth()] + ' ' + vkLastProfileEditDate.getFullYear() + ' в ' + vkLastProfileEditDate.getHours() + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getSeconds()) + '</div>';
  112. } else if (vkLang === 'uk') {
  113. vkLastProfileEditDateElement.innerHTML = '<div class="label fl_l">Останнє ред. стор.:</div><div class="labeled">' + vkLastProfileEditDate.getDate() + ' ' + vkMonthName[vkLastProfileEditDate.getMonth()] + ' ' + vkLastProfileEditDate.getFullYear() + ' о ' + vkLastProfileEditDate.getHours() + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getSeconds()) + '</div>';
  114. } else {
  115. vkLastProfileEditDateElement.innerHTML = '<div class="label fl_l">Last profile edit:</div><div class="labeled">' + addLeadingZeroToDate(vkLastProfileEditDate.getDate()) + '.' + addLeadingZeroToDate(vkLastProfileEditDate.getMonth() + 1) + '.' + vkLastProfileEditDate.getFullYear() + ' ' + addLeadingZeroToDate(vkLastProfileEditDate.getHours()) + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastProfileEditDate.getSeconds()) + '</div>';
  116. }
  117. vkProfilePage.replaceChild(vkLastProfileEditDateElement, vkProfilePage.childNodes[2]);
  118. } else {
  119. console.info('Last profile editing date on VK FOAF profile is empty or unavailable');
  120. }
  121. if (vkFoafLastSeenDate) {
  122. var vkLastSeenDate = new Date(vkFoafLastSeenDate);
  123. var vkLastSeenDateElement = document.createElement('div');
  124. vkLastSeenDateElement.className = 'clear_fix profile_info_row';
  125. if (vkLang === 'en') {
  126. vkLastSeenDateElement.innerHTML = '<div class="label fl_l">Last seen:</div><div class="labeled">' + vkMonthName[vkLastSeenDate.getMonth()] + ' ' + vkLastSeenDate.getDate() + ', ' + vkLastSeenDate.getFullYear() + ' at ' + convert24HoursTo12Hours(vkLastSeenDate.getHours()) + ':' + addLeadingZeroToDate(vkLastSeenDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastSeenDate.getSeconds()) + ' ' + convert24HoursToAmPmLc(vkLastSeenDate.getHours()) + '</div>';
  127. } else if (vkLang === 'ru') {
  128. vkLastSeenDateElement.innerHTML = '<div class="label fl_l">Последний заход:</div><div class="labeled">' + vkLastSeenDate.getDate() + ' ' + vkMonthName[vkLastSeenDate.getMonth()] + ' ' + vkLastSeenDate.getFullYear() + ' в ' + vkLastSeenDate.getHours() + ':' + addLeadingZeroToDate(vkLastSeenDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastSeenDate.getSeconds()) + '</div>';
  129. } else if (vkLang === 'uk') {
  130. vkLastSeenDateElement.innerHTML = '<div class="label fl_l">Останній візит:</div><div class="labeled">' + vkLastSeenDate.getDate() + ' ' + vkMonthName[vkLastSeenDate.getMonth()] + ' ' + vkLastSeenDate.getFullYear() + ' о ' + vkLastSeenDate.getHours() + ':' + addLeadingZeroToDate(vkLastSeenDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastSeenDate.getSeconds()) + '</div>';
  131. } else {
  132. vkLastSeenDateElement.innerHTML = '<div class="label fl_l">Last seen:</div><div class="labeled">' + addLeadingZeroToDate(vkLastSeenDate.getDate()) + '.' + addLeadingZeroToDate(vkLastSeenDate.getMonth() + 1) + '.' + vkLastSeenDate.getFullYear() + ' ' + addLeadingZeroToDate(vkLastSeenDate.getHours()) + ':' + addLeadingZeroToDate(vkLastSeenDate.getMinutes()) + ':' + addLeadingZeroToDate(vkLastSeenDate.getSeconds()) + '</div>';
  133. }
  134. vkProfilePage.replaceChild(vkLastSeenDateElement, vkProfilePage.childNodes[3]);
  135. } else {
  136. console.info('Last seen date on VK FOAF profile is empty or unavailable');
  137. }
  138. } else if (this.readyState === 4 && this.status !== 200) {
  139. console.error('Failed to get VK FOAF profile (registration date, last profile edit date and last seen date): ' + this.status + ' ' + this.statusText);
  140. }
  141. };
  142. requestVkFoaf.open('GET', '/foaf.php?id=' + vkProfileId, true);
  143. requestVkFoaf.send();
  144. }).observe(document.body, { childList: true, subtree: true });
  145. })();