Greasy Fork 支持简体中文。

LORCode Tools Native

Кнопка цитирования выделенного и панель тегов для LORCode

  1. // ==UserScript==
  2. // @name LORCode Tools Native
  3. // @description Кнопка цитирования выделенного и панель тегов для LORCode
  4. // @author Алексей Соловьев aka moscwich
  5. // @author Емельянов Эдуард aka Eddy_Em -- Fork && upgrade
  6. // @license Creative Commons Attribution 3.0 Unported
  7. // @version 0.21.4
  8. // @grant none
  9. // @namespace http://www.linux.org.ru/*
  10. // @namespace https://www.linux.org.ru/*
  11. // @include http://www.linux.org.ru/*
  12. // @include https://www.linux.org.ru/*
  13. // ==/UserScript==
  14.  
  15. // Based on MultiCodePanel 2.2 (v. 0.22)
  16. // http://al-moscwich.tk/tag/multicodepanel
  17.  
  18. function noDef(evt){ // remove default event action
  19. evt.stopPropagation();
  20. evt.preventDefault();
  21. }
  22.  
  23. function removeElements () {
  24. for (i = arguments.length-1; i > -1; i--) {
  25. var p = arguments[i].parentNode;
  26. if (p) p.removeChild (arguments[i]);
  27. }
  28. }
  29.  
  30. function set (p, z) {
  31. for (i = 0; i < arguments.length && (arguments[i] === undefined); i++) {}
  32. return arguments[i];
  33. }
  34.  
  35. i = j = undefined;
  36. a = b = undefined;
  37.  
  38. form = document.getElementById ("commentForm") || document.getElementById ("messageForm") || document.getElementById ("changeForm").getElementsByTagName ("label")[7];
  39. msg = document.getElementById ("msg") || document.getElementById ("form_msg") || document.getElementById ("info");
  40. var u = window.location.href;
  41.  
  42. // Panel
  43. var panel = document.createElement ("div");
  44. panel.id = 'atag';
  45. panel.createBlock = function () {
  46. block = document.createElement ("span");
  47. for (i = 0; i < arguments.length; i++) {
  48. link = document.createElement ("a");
  49. link.className = 'btn btn-default';
  50. link.textContent = arguments[i][0];
  51. link.title = arguments[i][1];
  52. link.exec = arguments[i][2];
  53. link.onclick = function(e){
  54. noDef(e);
  55. eval(this.exec);
  56. return false;
  57. };
  58. block.appendChild (link);
  59. }
  60. return this.appendChild (block);
  61. };
  62. panel.createBlock (
  63. ["[b]", "Полужирный", 'intag ("b");'],
  64. ["[i]", "Курсив", 'intag ("i");'],
  65. ["[s]", "Зачеркнутый", 'intag ("s");'],
  66. ["[u]", "Подчеркнутый", 'intag ("u");']
  67. );
  68. panel.createBlock (
  69. ["[quote]", "Цитата", 'intag ("quote", "\\n");'],
  70. ["[code]", "Код", 'intag ("code", "\\n");'],
  71. ["[inline]", "Внутристрочный код", 'intag ("inline");'],
  72. ["[pre]", "Код", 'intag ("pre", "\\n");']
  73. );
  74. panel.createBlock (
  75. ["[url]", "URL", 'url ();'],
  76. ["[user]", "Участник", 'intag ("user");']
  77. );
  78. panel.createBlock (
  79. ["[list]", "Список", 'lst();'],
  80. ["[*]", "Элемент списка", 'wrtSel ("[*]", "");']
  81. );
  82. panel.createBlock (
  83. ["«»", "Кавычки", 'wrtSel ("«", "»");'],
  84. /* ["„“", "Кавычки", 'wrtSel ("„", "“");'],*/
  85. ["[br]", "Перевод строки", 'wrtSel ("[br]", "");']
  86. );
  87. panel.createBlock (
  88. /* [" fix ", "Превратить знаки и обозначения в соответствующие спец. символы", 'fix();'],*/
  89. [" deltags ", "Удалить крайнее входящие обрамление тегами", 'deltagsin ();'],
  90. [" brs ", "Добавить [br] к переводам строк", 'brs ();']
  91. );
  92. panel.createBlock (
  93. ["[cut]", "Спойлер", 'cut ();']
  94. );
  95.  
  96. msg.parentNode.insertBefore (panel, msg);
  97. msg.cols = 100;
  98. msg.rows = 20;
  99.  
  100. // Styles
  101. obj = document.createElement ("style");
  102. obj.innerHTML = '#atag a {' +
  103. 'margin:1px;cursor: pointer;' +
  104. '-o-transform-origin: 14px 17px; background-color: rgb(39, 44, 45);' +
  105. 'border-bottom-color: rgb(114, 159, 207); border-bottom-left-radius: 5px;' +
  106. 'border-bottom-right-radius: 5px; border-bottom-style: solid;' +
  107. 'border-bottom-width: 1px; border-left-color: rgb(114, 159, 207);' +
  108. 'border-left-style: solid; border-left-width: 1px;' +
  109. 'border-right-color: rgb(114, 159, 207); border-right-style: solid;' +
  110. 'border-right-width: 1px; border-top-color: rgb(114, 159, 207);' +
  111. 'border-top-left-radius: 5px; border-top-right-radius: 5px;' +
  112. 'border-top-style: solid; border-top-width: 1px;' +
  113. 'color: rgb(114, 159, 207);' +
  114. 'font-family: "Trebuchet MS";' +
  115. 'display: inline !important;' +
  116. 'font-size: 14px; height: 22px; line-height: 22.4px !important; margin-bottom: 5px; margin-top: 5px; max-height: none;' +
  117. 'max-width: none; padding: 5px 4px !important; text-align: center;' +
  118. 'text-decoration: none;' +
  119. 'width: 16px;' +
  120. '}' +
  121. '#atag a:hover {background-color:rgb(84, 84, 84); border-color:rgb(186, 189, 182);}' +
  122. '#atag {' +
  123. 'margin-top: 5px; margin-bottom: 5px;' +
  124. 'padding: 3px 1px; font-size: 0.9em;' +
  125. '}' +
  126. '#atag > span {margin-right: 3px;}' +
  127. 'label[for="msg"] {display: inline-block; margin-top: 5px;}' +
  128. '#msg {width: 50em !important;}' +
  129. 'label[for="title"], label[for="form_mode"] {display: inline-block; margin: 5px 0 3px 0;}' +
  130. '.msg_body p {margin: 0.3em 0 !important;}' +
  131. '.quote > p {margin: 0.5em 0 0.3em 0 !important;}';
  132. document.getElementsByTagName ("head")[0].appendChild (obj);
  133.  
  134. // Remove formating tips
  135. // COMMENTED (I don't know why, but it breaks whole script)
  136. /*if (u.indexOf ("add.jsp") <= -1 &&
  137. u.indexOf ("edit.jsp") <= -1 &&
  138. u.indexOf ("register.jsp") <= -1)
  139. removeElements (form.getElementsByTagName ('font')[0],
  140. (i = form.getElementsByTagName ('br'))[5],
  141. i[6]
  142. );*/
  143.  
  144. // Add quote links
  145. function cre_links(o, L){
  146. var S = document.createElement("span");
  147. console.log("LEN: " + L.length + " obj: " + o);
  148. var Ll = L.length;
  149. for (j = 0; j < Ll; j++){
  150. qlink = document.createElement ("a");
  151. qlink.textContent = L[j][0];
  152. d = document.createElement("span");
  153. if(L[j][0] == "#"){
  154. qlink.href = getMsgURL(o);
  155. }else{
  156. qlink.href = "#";
  157. }
  158. d.onclick = L[j][1];
  159. d.innerHTML = "[" + qlink.outerHTML + "] ";
  160. S.appendChild(d);
  161. }
  162. if(o.firstElementChild && o.firstElementChild.nodeName != "IMG"){
  163. clink = o.firstChild;
  164. o.insertBefore(S, clink);
  165. }else
  166. o.appendChild(S);
  167. }
  168.  
  169. var t = document.getElementsByClassName("title");
  170. t.createQlink = function(){
  171. for (i = 0; i < this.length; i++){
  172. if(this[i].parentNode.nodeName != "ARTICLE") continue;
  173. var A = Array.prototype.slice.call(arguments);
  174. cre_links(this[i], A);
  175. }
  176. };
  177.  
  178. // Add \n to <br>
  179. var mbs = document.getElementsByClassName("msg_body");
  180. for (var j in mbs) if (!isNaN (j)) {
  181. var mps = mbs[j].getElementsByTagName ("p");
  182. for (var i in mps)
  183. if (!isNaN (i))
  184. mps[i].innerHTML = mps[i].innerHTML.replace (/<br\/?>(?![\n\r])/g, "<br>\n");
  185. }
  186.  
  187.  
  188. /* Main */
  189.  
  190. // Auxiliary functions
  191. function wrtSel(subj, offset, before, after, zset){ //Also msg.wrtSel (before, after, offset)
  192. if(typeof offset == "string") {
  193. after = offset;
  194. offset = before;
  195. before = subj;
  196. subj = undefined;
  197. }
  198. before = before || "";
  199. after = after || "";
  200. offset = set (offset, before.length);
  201. zset = zset || 0;
  202. startSel = set (a, msg.selectionStart);
  203. endSel = set (b, msg.selectionEnd);
  204. subj = before + set (subj, msg.value.substring (startSel, endSel)) + after;
  205.  
  206. msg.value = msg.value.substring (0, startSel) + subj + msg.value.substring (endSel);
  207. msg.selectionStart = msg.selectionEnd = startSel+offset;
  208. msg.focus();
  209. a = b = undefined;
  210. }
  211.  
  212. function lst(){
  213. a = msg.selectionStart; b = msg.selectionEnd;
  214. z = msg.value.substring(a, b).replace(/([^\n\r]+)[\n\r]*/g, "[*]$1\n");
  215. z = z.replace(/^[\s\r\n]+/g, '').replace(/^$/g,'');
  216. if(z.length === 0) z = "[*]\n";
  217. wrtSel(z, 6, "\n[list]\n", "[/list]\n");
  218. }
  219.  
  220. function addbr (c) {
  221. return c.replace (/^((?:(?!\[\/?(?:quote|code|list|br)(?:=.*)?\]$)[^\n\r])+)(\r?\n)(?!\n|\[\/?(?:br|quote(?:=.*)?|code(?:=.*)?)\])/gm, "$1[br]$2");
  222. }
  223.  
  224. function getTextContent (post) {
  225. var text = "";
  226. var pTags = post.getElementsByClassName ("msg_body")[0].getElementsByTagName ("p");
  227. for (i = 0; i < pTags.length; i++)
  228. if (pTags[i].parentNode.className.indexOf ('msg_body') > -1) {
  229. text += pTags[i].textContent;
  230. if (i != pTags.length - 1) text += "\n\n";
  231. }
  232. return text;
  233. }
  234.  
  235. function getUserName(evt){
  236. var post = getMsg(evt.target);
  237. if (i == post.getElementsByClassName("sign")[0].getElementsByTagName("a")[0])
  238. return i.innerHTML;
  239. else return "anonymous";
  240. }
  241.  
  242. // Functions to run
  243. function intag (tag, arg) {
  244. arg = arg || "";
  245. wrtSel(
  246. undefined,
  247. tag.length + 2 + arg.length*2,
  248. arg + "[" + tag + "]" + arg,
  249. arg + "[/" + tag + "]" + arg
  250. );
  251. }
  252.  
  253. // reparce quotations if checked in glob settings
  254. function reparce(text){
  255. var bef = text.split("[code]");
  256. bef[0] = bef[0].replace(/"/g, "&#34;");
  257. var N = bef.length;
  258. for(var m = 1; m < N; m++){
  259. var aft = bef[m].split("[/code]");
  260. aft[1] = aft[1].replace(/"/g, "&#34;");
  261. bef[m] = aft.join("[/code]");
  262. }
  263. text = bef.join("[code]");
  264. return text;
  265. }
  266.  
  267. function fix () {
  268. var a = msg.selectionStart, b = msg.selectionEnd;
  269. var repc = function (c) {
  270. c = c.replace (/\(c\)/gi, "©"); c = c.replace (/\([rр]\)/gi, "®");
  271. c = c.replace (/\(f\)/gi, "£"); c = c.replace (/\(e\)/gi, "€");
  272. c = c.replace (/%\/10/g, "‰"); c = c.replace (/%\/100/g, "‱");
  273. c = c.replace (/\(V\)/g, "✓"); c = c.replace (/\(V\+\)/g, "✔");
  274. c = c.replace (/\(x\)/g, "✗"); c = c.replace (/\(x\+\)/g, "✘");
  275. c = c.replace (/`/g, "&#769;"); c = c.replace (/\(p\)/gi, "§");
  276. c = c.replace (/(^| )- /g, "$1— "); c = c.replace (/\.\.\./g, "…");
  277. c = c.replace (/\(\*\+?\)/g, "★"); c = c.replace (/\(\*-\)/g, "☆");
  278. c = c.replace (/\([tт][mм]\)/gi, "™");
  279. c = c.replace (/-->/g, "→");
  280. return c;
  281. };
  282.  
  283. if (a != b) {
  284. var c = msg.value.substring (a, b);
  285. var z = repc (c);
  286. wrtSel(z, 0, "", "", z.length - c.length);
  287. }
  288. else
  289. msg.value = repc (msg.value);
  290. }
  291.  
  292. function url(U){
  293. U = U || "";
  294. a = msg.selectionStart; b = msg.selectionEnd;
  295. z = msg.value.substring (a, b);
  296. if(U !== ""){
  297. wrtSel (z, 6+U.length,
  298. "[url=" + U + "]", "[/url]",
  299. -z.length
  300. );
  301. }
  302. else if (/((ftp|http|https):\/\/)[\.\w- ]{2,}\.[A-Za-z]{2,4}(\/?$|\/.*)/.test(z) || z.length === 0) {
  303. wrtSel (z, z.length+6,
  304. "[url=", "][/url]"
  305. );
  306. }
  307. else if (/[\.\w- ]{2,}\.[A-Za-z]{2,4}(\/?$|\/.*)/.test(z)) {
  308. wrtSel (
  309. "http://"+z, z.length+13,
  310. "[url=", "][/url]", 7
  311. );
  312. }
  313. else {
  314. wrtSel (z, 5,
  315. "[url=]", "[/url]",
  316. -z.length
  317. );
  318. }
  319. }
  320.  
  321. function cut(C){
  322. var U = U || "";
  323. a = msg.selectionStart; b = msg.selectionEnd;
  324. z = msg.value.substring (a, b);
  325. wrtSel (z, 5,"[cut]", "[/cut]",-z.length);
  326. }
  327.  
  328. function deltagsin () {
  329. z = msg.value.substring (a = msg.selectionStart, b = msg.selectionEnd);
  330. c = z.replace (/\[\w+\](.*)\[\/\w+\]/, "$1");
  331. wrtSel (c, 0, "", "", - z.length + c.length);
  332. }
  333.  
  334. function brs () {
  335. var a = msg.selectionStart, b = msg.selectionEnd;
  336. if (a != b) {
  337. var c = msg.value.substring (a, b);
  338. var z = addbr (c);
  339. wrtSel (z, 0, "", "", z.length - c.length);
  340. }
  341. else {
  342. msg.value = addbr (msg.value);
  343. }
  344. }
  345.  
  346. function substTags(chN){
  347. if(!chN) return;
  348. var LORtagz = [ "b", "i","s","u","url","code","list","br","*","em","strong",
  349. "pre", "quote"];
  350. var txt = "", incode = false, latex = false;
  351. var Tpre="", Tpost="";
  352. if(chN.className == "sign" || chN.className == "reply") return "";
  353. if(chN.nodeName == "B"){Tpre="[b]"; Tpost="[/b]";}
  354. else if(chN.nodeName == "I"){Tpre="[i]"; Tpost="[/i]";}
  355. else if(chN.nodeName == "S"){Tpre="[s]"; Tpost="[/s]";}
  356. else if(chN.nodeName == "U"){Tpre="[u]"; Tpost="[/u]";}
  357. else if(chN.nodeName == "A"){Tpre="[url="+chN.href+"]"; Tpost="[/url]";}
  358. else if(chN.nodeName == "CODE"){Tpre="\n[code"+(chN.className ? "="+chN.className:"")+"]\n"; Tpost="[/code]"; incode = true;}
  359. else if(chN.nodeName == "UL"){Tpre="\n[list]\n"; Tpost="\n[/list]";}
  360. else if(chN.nodeName == "OL"){Tpre="\n[list=\""+chN.type+"\"]\n"; Tpost="\n[/list]";}
  361. else if(chN.nodeName == "BR")Tpost="[br]\n";
  362. else if(chN.nodeName == "LI"){Tpre="[*] "; Tpost="\n";}
  363. else if(chN.nodeName == "EM"){Tpre="[em]"; Tpost="[/em]";}
  364. else if(chN.nodeName == "STRONG"){Tpre="[strong]"; Tpost="[/strong]";}
  365. else if(chN.nodeName == "PRE"){Tpre="[pre]\n"; Tpost="[/pre]";}
  366. else if(chN.nodeName == "P"){Tpre="\n"; Tpost="\n";}
  367. else if(chN.nodeName == "SPAN"){Tpre=""; Tpost="\n";}
  368. else if(chN.nodeName == "CITE"){Tpre="[b]"; Tpost="[/b][br]\n";}
  369. else if(chN.nodeName == "IMG"){Tpre="[latex]"; Tpost="[/latex]"; latex = true;}
  370. //else if(chN.nodeName == ""){Tpre=""; Tpost="";}
  371. else if(chN.className == "quote"){Tpre="[quote]"; Tpost="[/quote]";}
  372. if(latex) txt = chN.title;
  373. else if(incode) txt = chN.textContent;
  374. else if(chN.childNodes && chN.childNodes.length)
  375. for (var ch in chN.childNodes)
  376. txt += substTags(chN.childNodes[ch]);
  377. else if(typeof(chN.textContent) != "undefined"){
  378. txt = chN.textContent; //.replace(/\[/g, '[[').replace(/\]/g, ']]');
  379. for(var j in LORtagz){
  380. var Tg = LORtagz[j];
  381. txt = txt.split("["+Tg+"]").join("[["+Tg+"]]");
  382. txt = txt.split("[/"+Tg+"]").join("[[/"+Tg+"]]");
  383. }
  384. }
  385. txt = Tpre + txt + Tpost;
  386. return txt.replace(/^[\s\r\n]+$/, '').replace(/^$/,'');
  387. }
  388.  
  389. function qb(e){
  390. noDef(e);
  391. var post, seltxt = getSelection ();
  392. function f(s,o){
  393. return "[quote" + (getMsg(o) != getMsg(msg) ? "=" + getUserName (e) : "") +
  394. "]" + substTags(s) + "\n[/quote]\n\n";
  395. }
  396. if (seltxt !== "") {
  397. post = getMsg(seltxt.getRangeAt(0).commonAncestorContainer);
  398. wrtSel(i = f(seltxt.getRangeAt (0).cloneContents(),this), i.length);
  399. }
  400. else {
  401. post = getMsg(this);
  402. wrtSel (i = f(post.getElementsByClassName ("msg_body")[0], this), i.length);
  403. }
  404. return false;
  405. }
  406.  
  407. function q(e) {
  408. noDef(e);
  409. var seltxt = getSelection ();
  410. if (seltxt !== "") {
  411. post = getMsg(seltxt.getRangeAt(0).commonAncestorContainer);
  412. wrtSel (i = seltxt.toString ().replace (/(\n\r?|^)(?:\n\r?)?/g, "$1> ") + "\r\n", i.length);
  413. }
  414. else {
  415. post = getMsg(this);
  416. wrtSel (i = getTextContent (post).replace (/(\n\r?|^)(?:\n\r?)?/g, "$1> ") + "\r\n", i.length);
  417. }
  418. return false;
  419. }
  420.  
  421. function user (e) {
  422. noDef(e);
  423. if ((i = getUserName(e)) != "anonymous")
  424. wrtSel (i = "[user]" + i + "[/user], ", i.length);
  425. else wrtSel (i = "[strong]Аноним[/strong], ", i.length);
  426. return false;
  427. }
  428.  
  429. function insurl(e){
  430. noDef(e);
  431. url(e.target.href);
  432. }