Trello - Thenow Trello Extend

Extend trello.com

  1. // Generated by CoffeeScript 1.12.2
  2.  
  3. /*
  4. // ==UserScript==
  5. // @name Trello - Thenow Trello Extend
  6. // @namespace http://ejiasoft.com/
  7. // @version 1.1.7
  8. // @description Extend trello.com
  9. // @description:zh-CN 扩展trello.com看板的功能
  10. // @homepageurl https://github.com/thenow/ThenowTrelloExtend
  11. // @author thenow
  12. // @run-at document-end
  13. // @license MIT license
  14. // @match http*://*trello.com
  15. // @match http*://*trello.com/*
  16. // @grant none
  17. // ==/UserScript==
  18. */
  19.  
  20. (function() {
  21. var addBgBtn, addBoardBtn, addImgSwitchBtn, addMemberToggleBtn, boardId, boardInit, btnClass, btnTextClass, cardLabelCss, curUrl, listCardFormat, listFormatInit, listTitleFormat, listToggle, pageRegex;
  22.  
  23. pageRegex = {
  24. CardLimit: /\[\d+\]/,
  25. Category: /\{.+\}/g,
  26. User: /`\S+`/g,
  27. CardCount: /^\d+/,
  28. Number: /\d+/,
  29. CardNum: /^#\d+/,
  30. HomePage: /com[\/]$/,
  31. BoardId: /\/b\/.{8}\/-$/
  32. };
  33.  
  34. curUrl = window.location.href;
  35.  
  36. boardId = pageRegex.BoardId.exec(curUrl);
  37.  
  38. cardLabelCss = "<style type=\"text/css\">\n .card-short-id {\n display: inline;\n font-weight: bold;\n }\n .card-short-id:after {\n content:\" \";\n }\n .column-list{padding:5px 15px 10px;}\n .column-list li{height:30px;width:100%;display:block;}\n .column-list li a{display:block;height:100%;line-height:30px;position:relative;}\n .column-list li a:before{font-family: trellicons;content:\"\\e910\";display:block;position:absolute;right:5px;top:2px;color:#333;}\n .column-list li a.false:before{content:\"-\";color:#DDD;}\n .card-label.mod-card-front {\n width: auto;\n height: 12px;\n line-height: 12px;\n font-size: 12px;\n text-shadow: none;\n padding: 3px 6px;\n font-family: Microsoft Yahei;\n font-weight: 400;\n }\n .list-card-title .card-short-id {\n display: inline;\n margin-right: 4px;\n color: #0079bf;\n }\n .list .list-header-num-cards {\n display: block;\n font-size: 12px;\n line-height: 18px;\n }\n</style>";
  39.  
  40. listCardFormat = function(objCard) {
  41. var listCardTitle;
  42. return listCardTitle = objCard.find('div.list-card-details>a.list-card-title').each(function() {
  43. var cardCate, cardCategoryArray, cardTitle, cardUser, cardUserArray, curCardTitle, i, j, len, len1, results;
  44. curCardTitle = $(this);
  45. cardTitle = curCardTitle.html();
  46. cardUserArray = cardTitle.match(pageRegex.User);
  47. cardCategoryArray = cardTitle.match(pageRegex.Category);
  48. if (cardUserArray !== null) {
  49. for (i = 0, len = cardUserArray.length; i < len; i++) {
  50. cardUser = cardUserArray[i];
  51. cardTitle = cardTitle.replace(cardUser, "<code>" + (cardUser.substring(1, cardUser.length - 1)) + "</code>");
  52. curCardTitle.html(cardTitle);
  53. }
  54. }
  55. if (cardCategoryArray !== null) {
  56. results = [];
  57. for (j = 0, len1 = cardCategoryArray.length; j < len1; j++) {
  58. cardCate = cardCategoryArray[j];
  59. cardTitle = cardTitle.replace(cardCate, "<code style=\"color:#0f9598\">" + (cardCate.substring(1, cardCate.length - 1)) + "</code>");
  60. results.push(curCardTitle.html(cardTitle));
  61. }
  62. return results;
  63. }
  64. });
  65. };
  66.  
  67. listTitleFormat = function(objList) {
  68. var cardCount, cardLimit, cardLimitInfo, curCardCountP, curListHeader, curListTitle;
  69. curListHeader = objList.find('div.list-header');
  70. curListTitle = curListHeader.find('textarea.list-header-name').val();
  71. cardLimitInfo = pageRegex.CardLimit.exec(curListTitle);
  72. if (cardLimitInfo === null) {
  73. return false;
  74. }
  75. curCardCountP = curListHeader.find('p.list-header-num-cards');
  76. cardCount = pageRegex.CardCount.exec(curCardCountP.text())[0];
  77. cardLimit = pageRegex.Number.exec(cardLimitInfo[0])[0];
  78. if (cardCount > cardLimit) {
  79. return objList.css('background', '#903');
  80. } else if (cardCount === cardLimit) {
  81. return objList.css('background', '#c93');
  82. } else {
  83. return objList.css('background', '#e2e4e6');
  84. }
  85. };
  86.  
  87. listToggle = function(objList) {
  88. var listMenu, toggleBtn;
  89. if (objList.find('.toggleBtn').length > 0) {
  90. return;
  91. }
  92. listMenu = objList.find('div.list-header-extras');
  93. toggleBtn = $('<a class="toggleBtn list-header-extras-menu dark-hover"><span class="icon-sm">隐</span></a>');
  94. toggleBtn.click(function() {
  95. var base;
  96. base = objList.parent();
  97. if (base.width() === 30) {
  98. base.css('width', '');
  99. } else {
  100. base.width(30);
  101. }
  102. objList.find('.js-open-list-menu').toggle();
  103. objList.find('div.list-cards').toggle();
  104. return objList.find('.open-card-composer').toggle();
  105. });
  106. return listMenu.append(toggleBtn);
  107. };
  108.  
  109. listFormatInit = function() {
  110. return $('div.list').each(function() {
  111. listTitleFormat($(this));
  112. listToggle($(this));
  113. return $(this).find('div.list-card').each(function() {
  114. return listCardFormat($(this));
  115. });
  116. });
  117. };
  118.  
  119. btnClass = 'board-header-btn board-header-btn-org-name board-header-btn-without-icon';
  120.  
  121. btnTextClass = 'board-header-btn-text';
  122.  
  123. addBoardBtn = function(id, text, eventAction, eventName) {
  124. var newBtn;
  125. if (eventName == null) {
  126. eventName = 'click';
  127. }
  128. if ($("#" + id).length > 0) {
  129. return $("#" + id);
  130. }
  131. newBtn = $("<a id=\"" + id + "\" class=\"" + btnClass + "\"><span class=\"" + btnTextClass + "\">" + text + "</span></a>");
  132. $('div.board-header').append(newBtn);
  133. if (eventAction !== null) {
  134. newBtn.bind(eventName, eventAction);
  135. }
  136. return newBtn;
  137. };
  138.  
  139. addImgSwitchBtn = function() {
  140. return addBoardBtn('btnImgSwitch', '隐藏/显示图片', function() {
  141. return $('div.list-card-cover').slideToggle();
  142. });
  143. };
  144.  
  145. addBgBtn = function() {
  146. return addBoardBtn('setBgBtn', '设置背景图片', function() {
  147. var newBgUrl, oldBgUrl;
  148. oldBgUrl = localStorage[boardId[0]];
  149. newBgUrl = prompt('请输入背景图片地址', oldBgUrl);
  150. if (newBgUrl === oldBgUrl) {
  151. return;
  152. }
  153. if (newBgUrl === null || newBgUrl === '') {
  154. localStorage.removeItem(boardId[0]);
  155. $('body').css('background-image', '');
  156. return;
  157. }
  158. return localStorage[boardId[0]] = newBgUrl;
  159. });
  160. };
  161.  
  162. addMemberToggleBtn = function() {
  163. return addBoardBtn('memberSwitchBtn', '隐藏/显示成员', function() {
  164. return $('div.list-card-members').slideToggle();
  165. });
  166. };
  167.  
  168. boardInit = function() {
  169. var bgUrl, localBgUrl;
  170. if (pageRegex.HomePage.exec(curUrl) !== null) {
  171. return;
  172. }
  173. bgUrl = $('body').css('background-image');
  174. localBgUrl = localStorage[boardId[0]];
  175. if (localBgUrl !== void 0 && bgUrl !== localBgUrl) {
  176. $('body').css('background-image', "url(\"" + localBgUrl + "\")");
  177. }
  178. $('p.list-header-num-cards').show();
  179. listFormatInit();
  180. addImgSwitchBtn();
  181. addBgBtn();
  182. return addMemberToggleBtn();
  183. };
  184.  
  185. $(function() {
  186. $('head').append(cardLabelCss);
  187. return setInterval((function() {
  188. curUrl = window.location.href;
  189. boardId = pageRegex.BoardId.exec(curUrl);
  190. return boardInit();
  191. }), 1000);
  192. });
  193.  
  194. }).call(this);