DTF.ru. Show me avatars (NEW)

Показ аватарок пользователей, а также копирование ссылки на аватарку. Курсор на аватарку и Ctrl для её показа, или Ctrl+Shift для копирования URL ссылки в буфер обмена.

目前为 2022-04-11 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name DTF.ru. Show me avatars (NEW)
  3. // @namespace https://github.com/TentacleTenticals
  4. // @match https://dtf.ru/*
  5. // @grant none
  6. // @version 1.0
  7. // @author Tentacle Tenticals
  8. // @description Показ аватарок пользователей, а также копирование ссылки на аватарку. Курсор на аватарку и Ctrl для её показа, или Ctrl+Shift для копирования URL ссылки в буфер обмена.
  9. // @homepage https://github.com/TentacleTenticals/DTF-showAvatar
  10. // @license MIT
  11. // ==/UserScript==
  12. /* jshint esversion:6 */
  13.  
  14. (function() {
  15. 'use strict';
  16. window.addEventListener('load', run);
  17. function run(){
  18. let css = document.createElement('style');
  19. css.textContent = `
  20. .searchmenuItem {
  21. display: block;
  22. background: white;
  23. color: black;
  24. border-radius: 3px;
  25. text-decoration: unset;
  26. border: unset;
  27. padding: 3px 10px 3px 10px;
  28. width: -webkit-fill-available;
  29. text-align: center;
  30. font-size: 12px;
  31. line-height: 12px;
  32. }
  33. .searchmenuItem:hover {
  34. background: rgb(213, 213, 239);
  35. }
  36.  
  37. .srcSearch {
  38. min-width: 100px;
  39. min-height: 100px;
  40. max-height: 500px;
  41. background: rgb(45, 5, 66);
  42. position: fixed;
  43. display: grid;
  44. grid-template-columns: repeat(1, auto);
  45. gap: 4px;
  46. align-content: center;
  47. justify-content: center;
  48. align-items: center;
  49. justify-items: center;
  50. padding: 10px;
  51. border-radius: 3px;
  52. z-index: 1000;
  53. }`
  54. document.body.appendChild(css);
  55.  
  56. let mainFilter = new RegExp(`comment__avatar|content-header-author__avatar|subsite-card__avatar|v-header__cover|v-header-avatar|${document.querySelector("div[class='layout__right-column'] div[style^='background-image").className}`),
  57. commentsRightBarFilter = new RegExp(document.querySelector("div[class='layout__right-column'] div[style^='background-image").className),
  58. button1Pressed, button2Pressed, button3Pressed, hovered,
  59. // Настройки клавиш. Используйте Control/Shift/Alt/и т.п. НЕ используйте буквы алфавита, цифры, знаки.
  60. useButton1ForAvatarView = true, // Использовать (true), или не использовать (false) button1 для показа аватарки.
  61. button1 = 'Control', // Клавиша для показа аватарки.
  62. button2 = 'Shift', // Клавиша, используемая в сочетании клавиш для копирования URL аватарки в буфер обмена.
  63. button3 = 'Alt', // Клавиша для показа поискового меню.
  64. // Настройки максимального размера превью аватарки
  65. userAvatarSize = '400px', // Аватарка пользователя (комментарий).
  66. userProfileCoverSizeWidth = '990px', // Обложка пользователя в профиле (длина).
  67. userProfileCoverSizeHeight = '400px', // Обложка пользователя в профиле (ширина).
  68. userProfileAvatarSize = '400px', // Аватар пользователя в профиле.
  69. authorAvatarSizeHeader = '400px', // Аватарка подсайта статьи (хеадер).
  70. authorAvatarSizeFooter = '400px', // Аватарка автора статьи (футер).
  71. userAvatarSizeCommentsPanel = '250px', // Аватарка пользователя (боковая панель комментариев, aka "live-список" комментариев к статьям).
  72. // Настройка вида превью аватарки
  73. imageBorderRadius = '3px', // Закругление углов.
  74. imageBackgroundColor = 'rgba(0, 0, 0, 1)', // Фон превью. Необходим, если аватарка это png и т.п. без фона.
  75. imageBoxShadow = '0px 0px 6px 2px black', // Тень, оставляемая элементом превью аватарки.
  76. // Список поисковиков, что вы хотите использовать. use:true/false (использовать)/(не использовать).
  77. // Можно добавить абсолютно любой "поиск по картинкам", главное это получить правильную ссылку для его работы.
  78. // url: - URL ссылка для работы поиска. name: - как будет называться этот поиск в поисковом меню.
  79. searches = [
  80. {url:'http://saucenao.com/search.php?db=999&url=', name:'Saucenao', use:true},
  81. {url:'https://www.bing.com/images/search?view=detailv2&iss=sbi&FORM=SBIHMP&sbisrc=UrlPaste&q=imgurl:', name:'Bing', use:true},
  82. {url:'https://www.google.com/searchbyimage?site=search&image_url=', name:'Google', use:true},
  83. {url:'https://yandex.ru/images/search?rdrnd=296405&rpt=imageview&url=', name:'Yandex', use:true},
  84. {url:'http://tineye.com/search/?url=', name:'TinEye', use:true},
  85. {url:'http://iqdb.org/?url=', name:'IQDB', use:true}
  86. ];
  87.  
  88. class A {
  89. constructor({name, searchUrl, targetUrl, elem}) {
  90. this.e=document.createElement('a');
  91. this.e.className=`searchmenuItem`
  92. this.e.textContent=name
  93. this.e.href=`${searchUrl}${targetUrl}`
  94. this.e.target='_blank'
  95. this.e.onclick = function(s){
  96. s.preventDefault()
  97. s.stopImmediatePropagation();
  98. window.open(s.target.href, '_blank');
  99. }
  100. elem.appendChild(this.e);
  101. return this.e;
  102. }
  103. }
  104.  
  105. function check(s){
  106. if(!useButton1ForAvatarView){
  107. hovered = s.target;
  108. return (!button1Pressed && !button2Pressed && !button3Pressed);
  109. }
  110. if(useButton1ForAvatarView){
  111. hovered = s.target;
  112. return (button1Pressed && !button2Pressed && !button3Pressed);
  113. }
  114. }
  115. document.addEventListener('mouseover', hover, true);
  116. function hover(s){
  117. if(s.target.classList.value.match(mainFilter) && check(s)){
  118. if(!document.querySelector(`div[class='avatar-preview']`)){
  119. let img = new Image();
  120. img.src = s.target.style.backgroundImage.replace(/.+(http.+)\/-\/scale.+/, '$1');
  121. let avatarPreview = document.createElement('div');
  122. avatarPreview.className = 'avatar-preview';
  123. avatarPreview.style.position = 'fixed';
  124. avatarPreview.style.zIndex = '1000';
  125. if(s.target.classList.value.match(/comment__avatar/)){
  126. avatarPreview.style.top = `${s.target.getBoundingClientRect().top + 20}px`;
  127. avatarPreview.style.left = `${s.target.getBoundingClientRect().left + 40}px`;
  128. img.style.maxWidth = userAvatarSize;
  129. img.style.maxHeight = userAvatarSize;
  130. }else
  131. if(s.target.classList.value.match(/v-header-avatar/)){
  132. avatarPreview.style.top = `${s.target.getBoundingClientRect().top + 170}px`
  133. avatarPreview.style.left = `${s.target.getBoundingClientRect().left + 20}px`
  134. img.style.maxWidth = userProfileAvatarSize;
  135. img.style.maxHeight = userProfileAvatarSize;
  136. }else
  137. if(s.target.classList.value.match(/v-header__cover/)){
  138. avatarPreview.style.top = `${s.target.getBoundingClientRect().top + 300}px`
  139. avatarPreview.style.left = `${s.target.getBoundingClientRect().left + 0}px`
  140. img.style.maxWidth = userProfileCoverSizeWidth;
  141. img.style.maxHeight = userProfileCoverSizeHeight;
  142. }else
  143. if(s.target.classList.value.match(/content-header-author__avatar/)){
  144. avatarPreview.style.top = `${s.target.getBoundingClientRect().top + 25}px`;
  145. avatarPreview.style.left = `${s.target.getBoundingClientRect().left + 40}px`;
  146. img.style.maxWidth = authorAvatarSizeHeader;
  147. img.style.maxHeight = authorAvatarSizeHeader;
  148. }else
  149. if(s.target.classList.value.match(/subsite-card__avatar/)){
  150. avatarPreview.style.top = `${s.target.getBoundingClientRect().top + 35}px`;
  151. avatarPreview.style.left = `${s.target.getBoundingClientRect().left + 50}px`;
  152. img.style.maxWidth = authorAvatarSizeFooter;
  153. img.style.maxHeight = authorAvatarSizeFooter;
  154. }else
  155. if(s.target.classList.value.match(commentsRightBarFilter)){
  156. avatarPreview.style.top = `${s.target.getBoundingClientRect().top + 25}px`;
  157. avatarPreview.style.left = `${s.target.getBoundingClientRect().left + 30}px`;
  158. img.style.maxWidth = userAvatarSizeCommentsPanel;
  159. img.style.maxHeight = userAvatarSizeCommentsPanel;
  160. }
  161. img.style.borderRadius = imageBorderRadius;
  162. img.style.backgroundColor = imageBackgroundColor;
  163. img.style.boxShadow = imageBoxShadow;
  164. s.target.parentNode.appendChild(avatarPreview);
  165. document.querySelector(`div[class='avatar-preview']`).appendChild(img);
  166. }
  167. }else
  168. if(s.target.classList.value.match(mainFilter) && !button1Pressed && !button2Pressed && button3Pressed) {
  169. if(!document.querySelector(`div[class='srcSearch']`) && hovered){
  170. console.log('Creating menu...');
  171. let menu = document.createElement('div');
  172. menu.className = 'srcSearch';
  173. if(s.target.classList.value.match(/v-header-avatar/)){
  174. menu.style.top = `${s.target.getBoundingClientRect().top + 120}px`;
  175. menu.style.left = `${s.target.getBoundingClientRect().left + 0}px`;
  176. }else
  177. {
  178. menu.style.top = `${s.target.getBoundingClientRect().top + 20}px`;
  179. menu.style.left = `${s.target.getBoundingClientRect().left + 20}px`;
  180. }
  181. hovered.parentNode.appendChild(menu);
  182.  
  183. for(let i = 0; i < searches.length; i++){
  184. if(searches[i].use){
  185. new A({
  186. name: searches[i].name,
  187. searchUrl: searches[i].url,
  188. targetUrl: hovered.style.backgroundImage.replace(/.+(http.+)\/-\/scale.+/, '$1'),
  189. elem: menu
  190. });
  191. }
  192. }
  193. }
  194. }else
  195. if(s.target.classList.value.match(mainFilter) && button1Pressed && button2Pressed && !button3Pressed){
  196. hovered = s.target;
  197. navigator.clipboard.writeText(s.target.style.backgroundImage.replace(/.+(http.+)\/-\/scale.+/, '$1'));
  198. if(!document.querySelector(`div[class='avatar-link-copyed']`)){
  199. let alert = document.createElement('div');
  200. alert.className = 'avatar-link-copyed';
  201. alert.textContent = 'Ссылка на аватарку успешно скопирована';
  202. alert.style.position = 'fixed';
  203. alert.style.zIndex = '1000';
  204. if(s.target.classList.value.match(/v-header-avatar/)){
  205. alert.style.top = `${s.target.getBoundingClientRect().top + 60}px`;
  206. alert.style.left = `${s.target.getBoundingClientRect().left + 0}px`;
  207. }else
  208. if(s.target.classList.value.match(/v-header__cover/)){
  209. alert.style.top = `${s.target.getBoundingClientRect().top + 300}px`;
  210. alert.style.left = `${s.target.getBoundingClientRect().left + 0}px`;
  211. }else
  212. if(s.target.classList.value.match(/comment__avatar|content-header-author__avatar|subsite-card__avatar/)){
  213. alert.style.top = `${s.target.getBoundingClientRect().top - 25}px`;
  214. alert.style.left = `${s.target.getBoundingClientRect().left + 20}px`;
  215. }else
  216. if(s.target.classList.value.match(commentsRightBarFilter)){
  217. alert.style.top = `${s.target.getBoundingClientRect().top - 25}px`;
  218. alert.style.left = `${s.target.getBoundingClientRect().left + 20}px`;
  219. }else
  220. {
  221. alert.style.top = `${s.target.getBoundingClientRect().top + 300}px`;
  222. alert.style.left = `${s.target.getBoundingClientRect().left + 0}px`;
  223. }
  224. alert.style.background = 'rgb(165 235 189)';
  225. alert.style.borderRadius = '3px';
  226. alert.style.padding = '3px';
  227. alert.style.color = 'rgb(0 0 0)';
  228. alert.style.fontSize = '12px';
  229. alert.style.lineHeight = '12px';
  230. alert.style.fontWeight = '500';
  231. alert.style.boxShadow = '0px 0px 6px 1px black';
  232. s.target.parentNode.appendChild(alert);
  233. setTimeout(() => {
  234. if(document.querySelector(`div[class='avatar-link-copyed']`)){
  235. document.querySelector(`div[class='avatar-link-copyed']`).remove();
  236. }
  237. }, 2000);
  238. }
  239. }else
  240. if(!s.target.classList.value.match(mainFilter) && button1Pressed && !button2Pressed && !button3Pressed){
  241. hovered = false;
  242. if(document.querySelector(`div[class='avatar-preview']`)){
  243. document.querySelector(`div[class='avatar-preview']`).remove();
  244. }
  245. }else
  246. if(!s.target.classList.value.match(mainFilter) && !button1Pressed && !button2Pressed){
  247. hovered = false;
  248. if(!useButton1ForAvatarView){
  249. if(document.querySelector(`div[class='avatar-preview']`)){
  250. document.querySelector(`div[class='avatar-preview']`).remove();
  251. }
  252. }
  253. }
  254. }
  255. document.addEventListener('keydown', kDown, true)
  256. function kDown(s){
  257. if(s.code === `${button1}Left`||s.code === `${button1}Right`||s.code === `${button1}`){
  258. button1Pressed = true;
  259. if(hovered){
  260. hovered.dispatchEvent(new MouseEvent('mouseover', {
  261. view: window,
  262. bubbles: true,
  263. cancelable: true
  264. }));
  265. }
  266. }else
  267. if(s.code === `${button2}Left`||s.code === `${button2}Right`||s.code === `${button2}`){
  268. button2Pressed = true;
  269. if(hovered){
  270. hovered.dispatchEvent(new MouseEvent('mouseover', {
  271. view: window,
  272. bubbles: true,
  273. cancelable: true
  274. }));
  275. }
  276. }else
  277. if(s.code === `${button3}Left`||s.code === `${button3}Right`||s.code === `${button3}`){
  278. button3Pressed = true;
  279. if(hovered){
  280. hovered.dispatchEvent(new MouseEvent('mouseover', {
  281. view: window,
  282. bubbles: true,
  283. cancelable: true
  284. }));
  285. }
  286. }
  287. }
  288. document.addEventListener('keyup', kUp, true)
  289. function kUp(s){
  290. if(s.code === `${button1}Left`||s.code === `${button1}Right`||s.code === `${button1}`){
  291. button1Pressed = false;
  292. }else
  293. if(s.code === `${button2}Left`||s.code === `${button2}Right`||s.code === `${button2}`){
  294. button2Pressed = false;
  295. }else
  296. if(s.code === `${button3}Left`||s.code === `${button3}Right`||s.code === `${button3}`){
  297. button3Pressed = false;
  298. if(document.querySelector(`div[class='srcSearch']`)){
  299. document.querySelector(`div[class='srcSearch']`).remove();
  300. }
  301. }
  302. if(document.querySelector(`div[class='avatar-preview']`)){
  303. document.querySelector(`div[class='avatar-preview']`).remove();
  304. }
  305. }
  306. ///
  307. }
  308. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址