Guest User

Untitled

a guest
Jan 12th, 2023
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 40.03 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Kalojop Extension Tools
  3. // @author sosman, pidorasta, kiee, inuyasha, Janes Megma, Linq (kovalgubanus) Kowalchek, Chmami, Dlinynos, サイバ民族, Yami
  4. // @description Калоскрипт для сучки
  5. // @version 1.3.8
  6. // @icon https://web.archive.org/web/20110211191032im_/http://1chan.ru/ico/favicon.ico
  7. // @match https://1chan.su/*
  8. // @match https://*.1chan.su/*
  9. // @match https://1chan.life/*
  10. // @match https://*.1chan.life/*
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function(document) {
  15.  
  16. // Globals
  17. var formTextarea;
  18. var deletingSmiles;
  19. var hidePatterns;
  20. var repliesTable = {};
  21. var locationPrefix = /\.(?:[a-z]{2,})\/([^/]+)/.exec(document.URL)[1]
  22.  
  23. const features = [
  24. 'answermap', 'hiding', 'smiles', 'markup', 'spoilers',
  25. 'show-hidden', 'recursive-hidding', 'form-settings', 'panel-hiding', 'markup-top',
  26. 'hide-short-news'
  27. ];
  28. const descriptions = [
  29. 'Построение карты ответов', 'Скрытие постов', 'Панель смайлов',
  30. 'Панель разметки', 'Раскрытие спойлеров', 'Показывать скрытые комментарии',
  31. 'Скрывать ответы на скрытый пост', 'Настройки рядом с формой', 'Убирать панель по клику',
  32. 'Разметка над формой', 'Скрывать новости короче 140 символов'
  33. ];
  34. const icons = {
  35. 'hide': "https://web.archive.org/web/20110225131301im_/http://static.1chan.ru/ico/oh-my-eyes.png",
  36. 'show': "https://web.archive.org/web/20110225131301im_/http://static.1chan.ru/ico/oh-my-eyes.png",
  37. 'addSmile': "https://web.archive.org/web/20220515043627if_/https://cdn1.iconfinder.com/data/icons/basicset/plus_16.png",
  38. 'redCross': "https://web.archive.org/web/20220606134547if_/https://1chan.su/ico/remove.gif",
  39. 'whiteCross': "https://web.archive.org/web/20220529165839if_/https://1chan.su/ico/delete.gif",
  40. 'settings': "https://web.archive.org/web/20190103061912if_/http://cdn1.iconfinder.com/data/icons/munich/16x16/settings.png",
  41. 'regexp': "https://web.archive.org/web/20120211134716if_/http://vll.java.net/images/GrammarIconRegex.gif"
  42. }
  43. var enabledFeatures;
  44. const VERSION = '100';
  45.  
  46.  
  47. /*
  48. * Replies map
  49. */
  50. /*
  51. * Replies map
  52. */
  53.  
  54. function createRepliesMap() {
  55.  
  56. var comments = document.getElementsByClassName("b-comment");
  57.  
  58. for(var i=0; i<comments.length; i++) {
  59. current_post = comments[i].id.slice(locationPrefix == 'news' ? 8 :
  60. (locationPrefix.length + 9) );
  61. var refs = comments[i].getElementsByClassName("js-cross-link");
  62. for(var j=0; j<refs.length; j++) {
  63. var ref = refs[j].name.slice(locationPrefix.length + 1);
  64. if(typeof(repliesTable[ref]) != 'undefined')
  65. repliesTable[ref].push(current_post);
  66. else
  67. repliesTable[ref] = [current_post];
  68. }
  69. }
  70. for(post_num in repliesTable) {
  71. container = document.createElement("div");
  72. container.id = "answers_"+post_num;
  73. container.appendChild(document.createElement('p'));
  74. container = container.lastChild;
  75. container.style.margin = '0px';
  76. container.style.padding = '4px';
  77. container.style.fontSize = '0.8em';
  78. container.textContent = "Ответы: ";
  79. for(post_ref in repliesTable[post_num]) {
  80. link = document.createElement("a");
  81. link.className = "js-cross-link";
  82. link.href = document.URL + '#'+repliesTable[post_num][post_ref];
  83. link.name = locationPrefix + "/" + repliesTable[post_num][post_ref];
  84. link.textContent = ">>"+repliesTable[post_num][post_ref];
  85. link.style.fontSize = '1em';
  86. container.appendChild(link);
  87. container.innerHTML += ', ';
  88. }
  89. container.innerHTML = container.innerHTML.substring(0, container.innerHTML.length-2);
  90. comment = document.getElementById("comment" +
  91. (locationPrefix == 'news' ? '_' : ('_' + locationPrefix + '_')) + post_num);
  92. if(comment)
  93. comment.appendChild(container.parentNode);
  94. }
  95. }
  96.  
  97. function registerAutoupdateHandler() {
  98. if(/\.ru\/news\/add/.test(document.URL))
  99. return;
  100. document.getElementsByClassName("l-comments-wrap")[0].addEventListener('DOMNodeInserted',
  101. function(event) {
  102. if(/comment/.test(event.target.id)) {
  103. // Hiding
  104. if(enabledFeatures.indexOf("hiding")!= -1) {
  105. var match = false;
  106. for(var j=0; j<hidePatterns.length; j++)
  107. if(hidePatterns[j].test(event.target.textContent)) {
  108. hidePost(event.target);
  109. break;
  110. }
  111. var hideButton = event.target.getElementsByClassName('b-comment_b-info')[0]
  112. .getElementsByClassName('js-remove-button')[0];
  113. hideButton.getElementsByTagName('img')[0].setAttribute("src", icons['hide']);
  114. hideButton.style.display = "inline-block";
  115. hideButton.onclick = function() {
  116. hidePost(this.parentNode.parentNode);
  117. return false;
  118. };
  119. }
  120. // Answer map
  121. if(enabledFeatures.indexOf("answermap")!= -1){
  122. refs = event.target.getElementsByClassName("js-cross-link");
  123. for(var j=0; j<refs.length; j++) {
  124. ref = refs[j].name.slice(locationPrefix.length + 1);
  125. link = document.createElement("a");
  126. link.className = "js-cross-link";
  127. var current_post = event.target.id.slice(locationPrefix == 'news' ? 8 :
  128. (locationPrefix.length + 9) );
  129. link.href = document.URL + '#' + current_post;
  130. link.name = locationPrefix + "/" + current_post;
  131. link.textContent = ">>" + current_post;
  132. link.style.fontSize = '1em';
  133. if(container = document.getElementById('answers_'+ref)) { // да, именно =
  134. container = container.lastChild
  135. container.innerHTML += ', ';
  136. container.appendChild(link)
  137. } else {
  138. container = document.createElement("div");
  139. container.id = "answers_" + ref;
  140. container.appendChild(document.createElement('p'));
  141. container = container.lastChild;
  142. container.style.margin = '0px';
  143. container.style.padding = '4px';
  144. container.style.fontSize = '0.8em';
  145. container.textContent = "Ответы: ";
  146. container.appendChild(link)
  147. comment = document.getElementById("comment" +
  148. (locationPrefix == 'news' ? '_' : ('_' + locationPrefix + '_'))
  149. + ref);
  150. if(comment)
  151. comment.appendChild(container.parentNode);
  152. }
  153. }
  154. }
  155. }
  156. });
  157. }
  158.  
  159.  
  160. /*
  161. * Hiding
  162. */
  163.  
  164. function hidePosts() {
  165. hidePatterns = [];
  166. var hiddenComments = [];
  167. var showedComments = [];
  168. for(var key in localStorage)
  169. if(/hidephrase/.test(key))
  170. hidePatterns.push(new RegExp(localStorage[key],"i"));
  171. else if(/^comment_/.test(key))
  172. hiddenComments.push(key);
  173. else if(/^temp_comment_/.test(key)) {
  174. var tempHidden = JSON.parse(localStorage.getItem(key));
  175. for (var i in tempHidden)
  176. hiddenComments.push(tempHidden[i]);
  177. }
  178.  
  179. var hideButtons = document.getElementsByClassName('js-remove-button');
  180. for(var i=0; i < hideButtons.length; i++) {
  181. hideButtons[i].getElementsByTagName('img')[0].setAttribute("src", icons['hide']);
  182. hideButtons[i].onclick = function() {
  183. hidePost(this.parentNode.parentNode);
  184. return false;
  185. }
  186. hideButtons[i].style.display = "inline-block";
  187. }
  188.  
  189. var comments = document.getElementsByClassName('b-comment');
  190. for(var i=0; i < comments.length; i++){
  191. for(var j=0; j < hidePatterns.length; j++)
  192. if(hiddenComments.indexOf(comments[i].id)!= -1 || hidePatterns[j].test(comments[i].textContent)) {
  193. hidePost(comments[i]);
  194. break;
  195. }
  196. }
  197. }
  198.  
  199. function hideThreads() {
  200. hidePatterns = [];
  201. for(var key in localStorage)
  202. if(/hidephrase/.test(key))
  203. hidePatterns.push(new RegExp(localStorage[key],"i"));
  204.  
  205. var threads = document.getElementsByClassName('b-blog-entry');
  206. for(var i=0; i < threads.length; i++) {
  207. var threadOpPost = threads[i].getElementsByClassName('b-blog-entry_b-body')[0].textContent;
  208. var threadTitle = threads[i].getElementsByClassName('b-blog-entry_b-header')[0].textContent;
  209. var hideShort = enabledFeatures.indexOf("hide-short-news")!= -1
  210. for(var j=0; j < hidePatterns.length; j++)
  211. if(
  212. hidePatterns[j].test(threadOpPost) ||
  213. hidePatterns[j].test(threadTitle) ||
  214. (hideShort && threadOpPost.length < 140)
  215. ) {
  216. hideThread(threads[i]);
  217. break;
  218. }
  219. }
  220. }
  221.  
  222. function hideThread(node) {
  223. if(enabledFeatures.indexOf("show-hidden")!= -1) {
  224. node.setAttribute("class", "b-blog-entry m-hide");
  225. var h = node.getElementsByClassName('b-blog-entry_b-header')[0];
  226. h.onclick = function() {
  227. showThread(node);
  228. return false;
  229. }
  230. } else {
  231. node.style.display = "none";
  232. }
  233. }
  234.  
  235. function showThread(node) {
  236. node.setAttribute("class", "b-blog-entry");
  237. var h = node.getElementsByClassName('b-blog-entry_b-header')[0];
  238. h.onclick = function() {};
  239. }
  240.  
  241. function hidePost(node, parentNode) {
  242. if(enabledFeatures.indexOf("show-hidden")!= -1) {
  243. node.getElementsByClassName('b-comment_b-body')[0].style.display = "none";
  244. var button = node.getElementsByClassName('b-comment_b-info')[0].getElementsByClassName('js-remove-button')[0];
  245. button.onclick = function() {
  246. showPost(node);
  247. return false;
  248. }
  249. button.getElementsByTagName('img')[0].setAttribute("src", icons['show']);
  250. } else {
  251. node.parentNode.removeChild(node);
  252. }
  253. if (enabledFeatures.indexOf("recursive-hidding") != -1) {
  254. var idPrefix = locationPrefix == 'news' ? 'comment_' : 'comment_' + locationPrefix + '_';
  255. var replies = repliesTable[node.id.slice(idPrefix.length)];
  256. for (var i in replies) {
  257. hidePost(document.getElementById(idPrefix + replies[i]), node);
  258. }
  259. }
  260. if (parentNode) {
  261. var tempHidden = JSON.parse(localStorage.getItem('temp_' + parentNode.id));
  262. if (tempHidden) {
  263. tempHidden.push(node.id);
  264. } else {
  265. tempHidden = [node.id];
  266. }
  267. localStorage.setItem('temp_' + parentNode.id, JSON.stringify(tempHidden));
  268. } else {
  269. localStorage.setItem(node.id, node.id);
  270. }
  271. return false;
  272. }
  273.  
  274. function showPost(node) {
  275. node.getElementsByClassName('b-comment_b-body')[0].style.display = "block";
  276. var button = node.getElementsByClassName('b-comment_b-info')[0].getElementsByClassName('js-remove-button')[0];
  277. button.onclick = function() {
  278. hidePost(node);
  279. return false;
  280. }
  281. button.getElementsByTagName('img')[0].setAttribute("src", icons['hide']);
  282. localStorage.removeItem(node.id);
  283. var tempHidden = JSON.parse(localStorage.getItem('temp_' + node.id));
  284. if (tempHidden) {
  285. for (var i in tempHidden) {
  286. showPost(document.getElementById(tempHidden[i]));
  287. }
  288. localStorage.removeItem('temp_' + node.id);
  289. }
  290. return false;
  291. }
  292.  
  293.  
  294. /*
  295. * Smiles Panel
  296. */
  297.  
  298. function addTextToForm(text) {
  299. cursor_pos = formTextarea.selectionStart;
  300. var formText = formTextarea.value;
  301. formTextarea.value = formText.slice(0, cursor_pos)
  302. + text
  303. + formText.slice(formTextarea.selectionEnd);
  304. formTextarea.focus();
  305. };
  306.  
  307. function wrapImageLink(link) {
  308. if (!link)
  309. return;
  310. if (/rghost/.test(link)) {
  311. var a = /rghost.ru\/([\d\w]{9})/.exec(link);
  312. if (a) {
  313. return '[:' + a[1] + ':]';
  314. }
  315. } else {
  316. return '[' + link + ']';
  317. }
  318. }
  319.  
  320. function createSmile(text, imgLink) {
  321.  
  322. var image = document.createElement("img");
  323. var link = document.createElement("a");
  324.  
  325. link.href = "#";
  326. link.onclick = function(e) {
  327. if (deletingSmiles) {
  328. destroyCustomSmile(this.id);
  329. } else {
  330. addTextToForm(text);
  331. formTextarea.focus();
  332. }
  333. e.preventDefault();
  334. return false;
  335. };
  336. link.title = text;
  337. image.src = imgLink;
  338. image.style.margin = "6px 3px 1px 3px";
  339. link.style.outline = "none";
  340. link.appendChild(image);
  341. return link;
  342. }
  343.  
  344. // Custom Images
  345.  
  346. function createCustomImage(link) {
  347.  
  348. var name = prompt("Имя для картинки:");
  349. if (!name)
  350. return false;
  351. var id = "image-" + name;
  352.  
  353. if (localStorage.getItem(id)) {
  354. alert("Уже есть картинка с таким именем");
  355. return false;
  356. }
  357. addCustomImage(link, name);
  358. localStorage.setItem(id, link);
  359. }
  360.  
  361. function addCustomImage(link, name) {
  362.  
  363. var id = "image-" + name;
  364. var newImage = createButton(name, function(e) {
  365. if (deletingSmiles)
  366. destroyCustomImage(this.id);
  367. else {
  368. addTextToForm(wrapImageLink(link));
  369. formTextarea.focus();
  370. }
  371. e.preventDefault();
  372. return false;
  373. });
  374.  
  375. newImage.onmousedown = function(e) {
  376. if (e.which === 2) {
  377. destroyCustomImage(this.id);
  378. }
  379. return false;
  380. };
  381.  
  382. newImage.id = id;
  383. newImage.setAttribute("class", "add-image-button");
  384.  
  385. var imageContainer = document.getElementById("image-container");
  386. imageContainer.appendChild(newImage);
  387. imageContainer.style.display = "block";
  388. }
  389.  
  390. function destroyCustomImage(id) {
  391. localStorage.removeItem(id);
  392. document.getElementById("image-container").removeChild(document.getElementById(id));
  393. if (document.getElementsByClassName("add-image-button").length === 0)
  394. document.getElementById("image-container").style.display = "none";
  395. }
  396.  
  397. // Custom Smiles
  398.  
  399. function createCustomSmile(link) {
  400.  
  401. var id = "smile-"+link;
  402.  
  403. if (localStorage.getItem(id)) {
  404. alert("Такой смайлик уже добавлен");
  405. return false;
  406. }
  407. addCustomSmile(link)
  408. localStorage.setItem(id, link);
  409. }
  410.  
  411. function addCustomSmile(link) {
  412.  
  413. var id = "smile-"+link;
  414. var wrappedLink = wrapImageLink(link);
  415. if (!wrappedLink)
  416. return;
  417. var newSmile = createSmile('"' + wrappedLink + '":' + link, link);
  418.  
  419. newSmile.onmousedown = function(e) {
  420. if (e.which === 2) {
  421. destroyCustomSmile(this.id);
  422. }
  423. return false;
  424. };
  425. newSmile.title = "Средняя кнопка мыши для удаления";
  426. newSmile.id = id;
  427. newSmile.setAttribute("class", "add-smile-link");
  428. document.getElementById("smile-panel").insertBefore(newSmile,
  429. document.getElementById("image-container"));
  430. }
  431.  
  432. function destroyCustomSmile(id) {
  433. localStorage.removeItem(id);
  434. document.getElementById("smile-panel").removeChild(document.getElementById(id));
  435. }
  436.  
  437. function addSmileClick(e) {
  438.  
  439. var link = prompt("Ссылка на картинку или номер файла в формате png:");
  440. var image = new Image();
  441.  
  442. if (!link)
  443. return false;
  444.  
  445. if (/([\d\w]{9})/.test(link))
  446. var num = /([\d\w]{9})/.exec(link)[1];
  447.  
  448. image.src = link;
  449. image.onerror = function() {
  450. if(num) {
  451. link = "https://files.catbox.moe/" + num + ".png";
  452. image.src = link;
  453. }
  454. image.onerror = function() {
  455. alert("Ошибка при загрузке картинки");
  456. }
  457. }
  458. image.onload = function() {
  459. if (image.width > 45 || image.heigth > 45) {
  460. createCustomImage(link);
  461. } else {
  462. createCustomSmile(link);
  463. }
  464. }
  465. e.preventDefault();
  466. return false;
  467. }
  468.  
  469. function removeSmilesClick(e) {
  470. const redCross = icons['redCross'];
  471. const whiteCross = icons['whiteCross'];
  472.  
  473. if (!deletingSmiles) {
  474. document.getElementById("remove-smiles-icon").src = whiteCross;
  475. deletingSmiles = true;
  476. } else {
  477. document.getElementById("remove-smiles-icon").src = redCross;
  478. deletingSmiles = false;
  479. }
  480. e.preventDefault();
  481. return false;
  482. }
  483.  
  484.  
  485. function createSmilePanel() {
  486.  
  487. var container = document.createElement("div");
  488. var gifSmileList = [ "sosak", "makak", "popka", "slon", "pauk", "cheez"];
  489. var pngSmileList = ["oru", "deb", "sheez", "you", "joseph", "yes", "projector"];
  490. var imageContainer = document.createElement("div");
  491.  
  492. for(var i in gifSmileList) {
  493. var newSmile = createSmile(':'+gifSmileList[i]+':', "http://1chan.su/img/" + gifSmileList[i] + ".gif");
  494. container.appendChild(newSmile);
  495. }
  496. for(var i in pngSmileList) {
  497. var newSmile = createSmile(':'+pngSmileList[i]+':', "http://1chan.su/img/" + pngSmileList[i] + ".png");
  498. container.appendChild(newSmile);
  499. }
  500.  
  501. var addSmileLink = document.createElement("a");
  502. var addSmileImg = document.createElement("img");
  503. addSmileImg.src = icons['addSmile'];
  504. addSmileLink.href = "#";
  505. addSmileLink.onclick = addSmileClick;
  506. addSmileLink.appendChild(addSmileImg);
  507. addSmileLink.title = "Добавить смайлик или картинку";
  508.  
  509. var removeSmilesLink = document.createElement("a");
  510. var removeSmilesImg = document.createElement("img");
  511. removeSmilesImg.src = icons['redCross'];
  512. removeSmilesImg.id = "remove-smiles-icon";
  513. removeSmilesLink.href = "#";
  514. removeSmilesLink.onclick = removeSmilesClick;
  515. removeSmilesLink.appendChild(removeSmilesImg);
  516. removeSmilesLink.title = "Удалить смайлики или картинки";
  517.  
  518. var controlsContainer = document.createElement("span");
  519. controlsContainer.style.cssFloat = "right";
  520. controlsContainer.style.margin = "5px";
  521.  
  522. controlsContainer.appendChild(addSmileLink);
  523. controlsContainer.appendChild(document.createElement("br"));
  524. controlsContainer.appendChild(removeSmilesLink);
  525.  
  526. container.appendChild(controlsContainer);
  527. container.style.minHeight = "50px";
  528.  
  529. if(/\.ru\/news\/add/.test(document.URL)) { // news/add
  530. container.style.width = '530px'
  531. container.style.border = "1px solid #999999";
  532. container.id = "smile-panel";
  533. document.getElementsByName('text_full')[0].parentNode.insertBefore(container,
  534. document.getElementsByName('text_full')[0]);
  535. }
  536. else {
  537. container.style.margin = "10px";
  538. container.style.paddingLeft = "8px";
  539. container.style.border = "1px solid #CCCCCC";
  540. container.style.borderRadius = "5px";
  541. container.id = "smile-panel";
  542. var formBody = formTextarea.parentNode.parentNode;
  543. formBody.parentNode.insertBefore(container, formBody);
  544. }
  545.  
  546. if(/\.ru\/news/.test(document.URL)) {
  547. var images = [];
  548. for(var i = 0; i < localStorage.length; i++) {
  549. var key = localStorage.key(i);
  550. if ((/^smile-/).test(key)) {
  551. var link = localStorage.getItem(key);
  552. addCustomSmile(link);
  553. } else if ((/^image-.+$/).test(key))
  554. images.push(key);
  555. }
  556.  
  557. imageContainer.id = "image-container";
  558. imageContainer.style.margin = "5px 6px 7px 0px";
  559. imageContainer.style.paddingTop = "2px";
  560. imageContainer.style.borderTop = "1px dashed #CCCCCC";
  561.  
  562. container.appendChild(imageContainer);
  563.  
  564. for(var i in images) {
  565. var name = /^image-(.+)$/.exec(images[i])[1];
  566. addCustomImage(localStorage.getItem(images[i]), name);
  567. }
  568.  
  569. if (images.length === 0) {
  570. imageContainer.style.display = "none";
  571. }
  572. }
  573.  
  574. if(enabledFeatures.indexOf("panel-hiding")!= -1)
  575. initSmilePanelHiding()
  576. }
  577.  
  578. function initSmilePanelHiding() {
  579.  
  580. var smilePanel = document.getElementById("smile-panel");
  581. var showButton = document.createElement("a");
  582. var showContainer = document.createElement("div");
  583. var hideButton = document.createElement("a");
  584. var hideContainer = document.createElement("div");
  585.  
  586. showButton.onclick = function() {
  587. showSmilePanel();
  588. return false;
  589. };
  590. showButton.textContent = "Cмайлики и картинки";
  591. showButton.style.borderBottom = "1px dashed #3366CC";
  592. showButton.style.textDecoration = "none";
  593. showButton.href = "#";
  594. showContainer.appendChild(showButton);
  595. showContainer.style.display = "none";
  596. showContainer.style.fontSize = "0.65em";
  597. showContainer.id = "show-panel-button";
  598.  
  599. hideButton.onclick = function() {
  600. hideSmilePanel();
  601. return false;
  602. };
  603. hideButton.textContent = "Спрятать панель";
  604. hideButton.style.borderBottom = "1px dashed #3366CC";
  605. hideButton.style.textDecoration = "none";
  606. hideButton.href = "#";
  607. hideContainer.appendChild(hideButton);
  608. hideContainer.style.fontSize = "0.65em";
  609. hideContainer.id = "hide-panel-button";
  610.  
  611. if(/\.ru\/news\/add/.test(document.URL)) {
  612. hideContainer.style.margin = "3px 0px 4px 220px";
  613. showContainer.style.margin = "3px 0px 4px 210px";
  614. } else {
  615. hideContainer.style.margin = "3px 0px -3px 240px";
  616. showContainer.style.margin = "3px 0px -3px 230px";
  617. }
  618.  
  619. smilePanel.parentNode.insertBefore(hideContainer, smilePanel);
  620. smilePanel.parentNode.insertBefore(showContainer, smilePanel);
  621.  
  622. if(localStorage.getItem("smile_panel") == "hidden")
  623. hideSmilePanel();
  624. }
  625.  
  626. function hideSmilePanel() {
  627. localStorage.setItem("smile_panel", "hidden");
  628. document.getElementById("smile-panel").style.display = "none";
  629. document.getElementById("show-panel-button").style.display = "block";
  630. document.getElementById("hide-panel-button").style.display = "none";
  631. }
  632.  
  633. function showSmilePanel() {
  634. localStorage.setItem("smile_panel", "visible");
  635. document.getElementById("smile-panel").style.display = "block";
  636. document.getElementById("show-panel-button").style.display = "none";
  637. document.getElementById("hide-panel-button").style.display = "block";
  638. }
  639.  
  640.  
  641. /*
  642. * Markup Panel
  643. */
  644.  
  645. function getSelectionText(node) {
  646. var start = node.selectionStart;
  647. var end = node.selectionEnd;
  648. return node.value.substring(start, end);
  649. }
  650.  
  651. function wrapText(text, wrapper) {
  652. return wrapper + text + wrapper;
  653. }
  654.  
  655. function createButton(value, onclick) {
  656. var button = document.createElement("input");
  657. button.type = "button";
  658. button.value = value;
  659. button.onclick = onclick;
  660. return button;
  661. }
  662.  
  663. function imgClick() {
  664.  
  665. var link = getSelectionText(formTextarea);
  666.  
  667. if (link.length > 0) {
  668. addTextToForm(wrapImageLink(link));
  669. } else {
  670. addTextToForm(wrapImageLink(prompt('Ссылка на изображение:')));
  671. }
  672. }
  673.  
  674. function quoteClick() {
  675.  
  676. var text = getSelectionText(formTextarea);
  677. var start = formTextarea.selectionStart;
  678.  
  679. if (text.length > 0) {
  680. var formText = formTextarea.value;
  681. var lines = text.split("\n");
  682. for(var i in lines) {
  683. lines[i] = ">>" + lines[i].trim() + "<<";
  684. }
  685. addTextToForm(lines.join("\n"));
  686. if(lines.length == 1)
  687. formTextarea.setSelectionRange(start + 2, start + text.length + 2);
  688. } else {
  689. text = document.getSelection().toString();
  690. var lines = text.split("\n");
  691. for(var i in lines) {
  692. lines[i] = ">" + lines[i].trim();
  693. }
  694. addTextToForm(lines.join("\n"));
  695. }
  696. }
  697.  
  698. function bigBoldClick() {
  699.  
  700. var text = getSelectionText(formTextarea);
  701. var lines = text.split("\n");
  702. var cursor = formTextarea.selectionEnd;
  703. var start = formTextarea.selectionStart;
  704. const stars = "\n********************************************";
  705.  
  706. if (text.length > 0) {
  707. for(var i in lines) {
  708. if (lines[i] !== "")
  709. lines[i] += stars;
  710. }
  711. addTextToForm(lines.join("\n"));
  712. } else {
  713. formTextarea.value += stars;
  714. }
  715.  
  716. formTextarea.focus();
  717. if(lines.length == 1 && text.length > 0)
  718. formTextarea.setSelectionRange(start, start + text.length);
  719. else
  720. formTextarea.setSelectionRange(cursor, cursor);
  721. }
  722.  
  723.  
  724.  
  725. function strikeThroughClick() {
  726. var text = getSelectionText(formTextarea);
  727. addTextToForm('<s>' + text + '</s>');
  728. }
  729.  
  730. function yobaClick() {
  731. var selected_text = getSelectionText(formTextarea);
  732. var has_selected = selected_text.length != 0;
  733.  
  734. if(has_selected)
  735. addTextToForm(yobaTranslate(selected_text));
  736. else
  737. formTextarea.value = yobaTranslate(formTextarea.value)
  738. }
  739.  
  740. function createMarkupPanel() {
  741.  
  742. var container = document.createElement("div");
  743. var markup = {
  744. "B": ["**", "Жирный"],
  745. "I": ["*", "Наклонный"],
  746. "C": ["`", "Моноширный"],
  747. "%": ["%%", "Спойлер"]
  748. };
  749.  
  750. var buttons = {
  751. "img": imgClick,
  752. ">": quoteClick,
  753. "S": strikeThroughClick,
  754. "BB": bigBoldClick,
  755. "Y": yobaClick
  756. };
  757.  
  758. for (var k in buttons)
  759. container.appendChild(createButton(k, buttons[k]));
  760.  
  761. for(var k in markup) {
  762. var newButton = createButton(k, function() {
  763. var text = getSelectionText(formTextarea);
  764. var start = formTextarea.selectionStart;
  765. var selection = formTextarea.selectionStart != formTextarea.selectionEnd;
  766. var m = markup[this.value][0];
  767. text = wrapText(text, m);
  768. addTextToForm(text);
  769. if(selection)
  770. formTextarea.setSelectionRange(start, start + text.length);
  771. else
  772. formTextarea.setSelectionRange(start + m.length, start + m.length);
  773. });
  774. container.appendChild(newButton);
  775. }
  776.  
  777. if(/\.ru\/news\/add/.test(document.URL)) {
  778. container.style.paddingTop = "4px";
  779. document.getElementsByName('text_full')[0].parentNode.insertBefore(container,
  780. document.getElementsByName('text_full')[0])
  781. document.addEventListener('click', function(event){
  782. if(/text/.test(event.target.name))
  783. formTextarea = event.target // Смена полей в news/add
  784. })
  785. } else {
  786. if(enabledFeatures.indexOf("markup-top") == -1) {
  787. container.style.display = "inline-block";
  788. formTextarea.parentNode.insertBefore(container,
  789. document.getElementsByClassName("b-comment-form_b-uplink")[0]);
  790. } else {
  791. container.style.marginTop = "3px";
  792. formTextarea.style.margin = "3px 0px 6px"
  793. formTextarea.parentNode.insertBefore(container, formTextarea);
  794. }
  795. }
  796. }
  797.  
  798.  
  799. /*
  800. * Spoilers
  801. */
  802.  
  803. function revealSpoilers() {
  804. var spoilers = document.getElementsByClassName('b-spoiler-text')
  805. for(var i = 0; i<spoilers.length; i++)
  806. spoilers[i].setAttribute('style', 'color:#40454B !important')
  807. }
  808.  
  809. /*
  810. * Yoba Translator
  811. */
  812. var yoba_main = {
  813. 'а': ["a"],
  814. 'б': ["b"],
  815. 'в': ["v"],
  816. 'г': ["g"],
  817. 'д': ["d"],
  818. 'е': ["ye", "e"],
  819. 'ё': ["yo"],
  820. 'ж': ["zh"],
  821. 'з': ["z"],
  822. 'и': ["i", "ee"],
  823. 'й': ["y", "j"],
  824. 'к': ["k", "ck", "q"],
  825. 'л': ["l"],
  826. 'м': ["m"],
  827. 'н': ["n"],
  828. 'о': ["o", "ou"],
  829. 'п': ["p"],
  830. 'р': ["r"],
  831. 'с': ["s"],
  832. 'т': ["t"],
  833. 'у': ["oo", "u"],
  834. 'ф': ["f"],
  835. 'х': ["kh"],
  836. 'ц': ["c"],
  837. 'ч': ["ch"],
  838. 'ш': ["sh"],
  839. 'щ': ["sh"],
  840. 'ы': ["y", "i"],
  841. 'э': ["e"],
  842. 'ю': ["yu"],
  843. 'я': ["ya"],
  844. };
  845.  
  846. var yoba_ends = {
  847. 'и': ["ey"],
  848. 'е': ["eu"],
  849. 'о': ["ou"],
  850. };
  851.  
  852. function pickRandomElement(arr) {
  853. if(arr.length == 0)
  854. return null;
  855. else if(arr.length == 1)
  856. return arr[0];
  857. else
  858. return arr[Math.floor(Math.random() * arr.length)];
  859. }
  860.  
  861. function yobaTranslate(str) {
  862. var result = "";
  863.  
  864. str = str.replace(/[ьъ]/gi, "");
  865.  
  866. for(var pos = 0; pos < str.length; pos++)
  867. {
  868. var from = str[pos];
  869. var to = '';
  870.  
  871. var is_upper = from == from.toUpperCase();
  872. from = from.toLowerCase();
  873.  
  874. if(yoba_ends[from] && (!str[pos + 1] || /[\s\.,!\?]/.test(str[pos + 1])))
  875. to = pickRandomElement(yoba_ends[from]);
  876. else if(yoba_main[from])
  877. to = pickRandomElement(yoba_main[from]);
  878. else
  879. to = from;
  880.  
  881. if(is_upper)
  882. to = to[0].toUpperCase() + to.slice(1);
  883.  
  884. result += to;
  885. }
  886.  
  887. return result;
  888. }
  889.  
  890. /*
  891. * Menu
  892. */
  893.  
  894. function createMenu() {
  895.  
  896. var general = document.createElement("a");
  897. var hidelist = document.createElement("a");
  898.  
  899. general.href = "#";
  900. general.onclick = displayGeneralOptions;
  901. general.id = "general-settings-button";
  902. hidelist.href = "#";
  903. hidelist.onclick = displayHideList;
  904. hidelist.id = "hiding-list-button";
  905. if(enabledFeatures.indexOf('form-settings')!= -1) {
  906. var generalIcon = document.createElement("img");
  907. generalIcon.src = icons['settings'];
  908. general.appendChild(generalIcon);
  909. var regexpIcon = document.createElement("img");
  910. regexpIcon.src = icons['regexp'];
  911. hidelist.appendChild(regexpIcon);
  912. var container = formTextarea.parentNode.parentNode.getElementsByTagName("div")[0];
  913. hidelist.style.cssFloat = "right";
  914. general.style.cssFloat = "right";
  915. general.style.margin = "0px 10px 0px 2px";
  916. general.title = "Настройки скрипта";
  917. hidelist.title = "Список скрываемых выражений";
  918. container.parentNode.insertBefore(general, container);
  919. container.parentNode.insertBefore(hidelist, container);
  920. } else {
  921. var container = document.getElementsByClassName("b-menu-panel_b-links")[0];
  922. general.textContent = "Настройки скрипта";
  923. hidelist.textContent = "Список скрываемых выражений";
  924. container.appendChild(general);
  925. container.appendChild(document.createElement("br"));
  926. container.appendChild(hidelist);
  927. }
  928. }
  929.  
  930. function hideGeneralOptions() {
  931. var cont = document.getElementById('scriptsettings');
  932. cont.parentNode.removeChild(cont);
  933. document.getElementById('general-settings-button').onclick = displayGeneralOptions;
  934. return false;
  935. }
  936.  
  937. function hideHideList() {
  938. var menu = document.getElementById('regexps').parentNode;
  939. menu.parentNode.removeChild(menu);
  940. document.getElementById('hiding-list-button').onclick = displayHideList;
  941. return false;
  942. }
  943.  
  944. function displayGeneralOptions() {
  945. var container = document.createElement("div");
  946. document.getElementById('general-settings-button').onclick = hideGeneralOptions;
  947. container.id = 'scriptsettings'
  948. container.setAttribute("style", 'top: 5px; left:5px; position:fixed; \
  949. z-index: 10000; background: #EAF4FF; padding: 5px');
  950. for(var i = 0; i < features.length; i++) {
  951. var desc = document.createElement('p');
  952. desc.textContent = descriptions[i];
  953. desc.style.display = 'inline';
  954. desc.style.fontSize = '0.75em'
  955. var box = document.createElement('input');
  956. box.type = 'checkbox';
  957. box.className = 'opt';
  958. box.id = features[i];
  959. container.appendChild(box);
  960. container.appendChild(desc);
  961. container.appendChild(document.createElement('br'));
  962. }
  963. btn = document.createElement("button");
  964. btn.textContent = "Сохранить";
  965. btn.href = "#";
  966. btn.onclick = saveGeneralOptions;
  967. container.appendChild(btn);
  968. document.getElementsByTagName("body")[0].appendChild(container)
  969. for(var i = 0; i<enabledFeatures.length; i++)
  970. if(enabledFeatures[i] != '')
  971. document.getElementById(enabledFeatures[i]).checked = true;
  972. return false;
  973. }
  974.  
  975. function saveGeneralOptions() {
  976. document.getElementById('general-settings-button').onclick = displayGeneralOptions;
  977. enabledFeatures = [];
  978. var boxes = document.getElementsByClassName('opt');
  979. for(var i = 0; i<boxes.length; i++)
  980. if(boxes[i].checked)
  981. enabledFeatures.push(boxes[i].id);
  982. var str = '';
  983. for(var i = 0; i < enabledFeatures.length; i++)
  984. str += enabledFeatures[i] + ' ';
  985. localStorage['settings' + VERSION] = str;
  986. cont = document.getElementById('scriptsettings');
  987. cont.parentNode.removeChild(cont)
  988. }
  989.  
  990. function displayHideList() {
  991. var container = document.createElement("div")
  992. document.getElementById('hiding-list-button').onclick = hideHideList;
  993. container.setAttribute("style", "top: 5px; left:5px; position:fixed; \
  994. z-index: 10000; background: #EAF4FF; border: 1px black")
  995. var list = document.createElement("textarea")
  996. list.id = "regexps"
  997. list.setAttribute("style", "width: 300px; height: 300px; margin:5px")
  998. for(var key in localStorage)
  999. if(/hidephrase/.test(key))
  1000. list.value += localStorage[key] + '\n'
  1001. var button = document.createElement("button")
  1002. button.textContent = "Сохранить"
  1003. button.onclick = updateRegexps;
  1004. button.style.margin = "5px"
  1005. container.appendChild(list)
  1006. container.appendChild(document.createElement("br"))
  1007. container.appendChild(button)
  1008. document.getElementsByTagName("body")[0].appendChild(container)
  1009. return false;
  1010. }
  1011.  
  1012. function updateRegexps() {
  1013. document.getElementById('hiding-list-button').onclick = displayHideList;
  1014. for(var key in localStorage)
  1015. if(/hidephrase/.test(key))
  1016. localStorage.removeItem(key);
  1017. regexps = document.getElementById('regexps').value.split('\n');
  1018. for(var i = 0; i < regexps.length; i++) {
  1019. if(regexps[i] != "") {
  1020. localStorage.setItem("hidephrase" + i, regexps[i]);
  1021. }
  1022. }
  1023. menu = document.getElementById('regexps').parentNode;
  1024. menu.parentNode.removeChild(menu);
  1025. }
  1026.  
  1027.  
  1028. /*
  1029. * Main
  1030. */
  1031.  
  1032. function letTheSobakOut() {
  1033. try {
  1034. enabledFeatures = localStorage['settings' + VERSION].split(' ');
  1035. } catch(keyerror) {
  1036. enabledFeatures = features;
  1037. var str = '';
  1038. for(var i = 0; i < features.length; i++ )
  1039. str += features[i] + ' ';
  1040. localStorage['settings' + VERSION] = str;
  1041. }
  1042.  
  1043. formTextarea = document.getElementById("comment_form_text");
  1044. if (!formTextarea)
  1045. formTextarea = document.getElementsByName("text")[0];
  1046. if (formTextarea) {
  1047. if(enabledFeatures.indexOf("answermap")!= -1)
  1048. createRepliesMap();
  1049. if(enabledFeatures.indexOf("hiding")!= -1)
  1050. hidePosts();
  1051. registerAutoupdateHandler();
  1052. deletingSmiles = false;
  1053. if(enabledFeatures.indexOf("markup")!= -1)
  1054. createMarkupPanel();
  1055. if(enabledFeatures.indexOf("smiles")!= -1)
  1056. createSmilePanel();
  1057. } else
  1058. if(enabledFeatures.indexOf("hiding")!= -1)
  1059. hideThreads();
  1060. if(enabledFeatures.indexOf("spoilers")!= -1)
  1061. revealSpoilers();
  1062. createMenu();
  1063.  
  1064. }
  1065.  
  1066. if(navigator.appName == "Opera")
  1067. document.addEventListener('DOMContentLoaded', letTheSobakOut);
  1068. else {
  1069. letTheSobakOut();
  1070. }
  1071.  
  1072. })(document);
Add Comment
Please, Sign In to add comment