Workflowier

User Script for Workflowy.com that adds some extra features.

当前为 2016-04-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Workflowier
  3. // @namespace Workflowier
  4. // @include *
  5. // @author Nick Busey
  6. // @description User Script for Workflowy.com that adds some extra features.
  7. // @match https://workflowy.com/#
  8. // @version 0.0.1.3
  9. // ==/UserScript==
  10.  
  11. // a function that loads jQuery and calls a callback function when jQuery has finished loading
  12. function addJQuery(callback) {
  13. var script = document.createElement("script");
  14. script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js");
  15. script.addEventListener('load', function() {
  16. var script = document.createElement("script");
  17. script.textContent = "window.jQ=jQuery.noConflict(true);(" + callback.toString() + ")();";
  18. document.body.appendChild(script);
  19. }, false);
  20. document.body.appendChild(script);
  21. }
  22.  
  23. searching = false;
  24.  
  25. // the guts of this userscript
  26. function main() {
  27. // Note, jQ replaces jQ to avoid conflicts.
  28. // Insert recent links
  29. jQ('#savedViewHUDButton').after("<div class='showCompletedButton button'><div class='topBarButtonTextContainer'><a href='#' id='recentLink_1wk'>This Week</a></div></div>");
  30. jQ('#recentLink_1wk').click(function(e) {
  31. e.preventDefault();
  32. if (jQ('#searchBox').val()=='last-changed:7d') {
  33. search.searchProjectTree('');
  34. } else {
  35. search.searchProjectTree('last-changed:7d');
  36. }
  37. });
  38. jQ('#savedViewHUDButton').after("<div class='showCompletedButton button'><div class='topBarButtonTextContainer'><a href='#' class='button' id='recentLink_24hrs'>Today</a></div></div>");
  39. jQ('#recentLink_24hrs').click(function(e) {
  40. e.preventDefault();
  41. if (jQ('#searchBox').val()=='last-changed:1d') {
  42. search.searchProjectTree('');
  43. } else {
  44. search.searchProjectTree('last-changed:1d');
  45. }
  46. });
  47. jQ('#savedViewHUDButton').after("<div class='showCompletedButton button'><div class='topBarButtonTextContainer'><a href='#' class='button' id='recentLink_1hr'>Just Now</a></div></div>");
  48. jQ('#recentLink_1hr').click(function(e) {
  49. e.preventDefault();
  50. if (jQ('#searchBox').val()=='last-changed:1h') {
  51. search.searchProjectTree('');
  52. } else {
  53. search.searchProjectTree('last-changed:1h');
  54. }
  55. });
  56. var generateTagsMenu = function() {
  57. var currentSearch = jQ('#searchBox').val();
  58. search.searchProjectTree('#');
  59. var tags = $('.contentTagText');
  60. // Generate list of all hashtags
  61. var tagObjs = {};
  62. tags.each(function(ii, obj) {
  63. // console.log(obj);
  64. // console.log(jQ(obj).text());
  65. var tag = jQ(obj).text();
  66.  
  67. var tagObj = tagObjs[tag];
  68. // console.log(tag,' - ',tagObj);
  69. if (!tagObj) {
  70. // console.log("No tag object, make an empty one.")
  71. tagObj = {'count':1};
  72. } else {
  73. tagObj['count']++;
  74. }
  75. tagObjs[tag] = tagObj;
  76. });
  77. // console.log(tagObjs);
  78. var tagObjsArray = [];
  79. for (var tag in tagObjs) {
  80. var tagObj = tagObjs[tag];
  81. tagObj['tag'] = tag;
  82. // console.log(tag,tagObj);
  83. tagObjsArray.push(tagObj);
  84. }
  85. // console.log(tagObjsArray);
  86. var sortedTagObjsArray = tagObjsArray.sort(function (a, b) {
  87. return a.count > b.count;
  88. });
  89. globTest = sortedTagObjsArray;
  90. // console.log(sortedTagObjsArray);
  91. var tagLinkOutput = '';
  92. for (var ii in sortedTagObjsArray) {
  93. var count = sortedTagObjsArray[ii]['count'];
  94. var tag = sortedTagObjsArray[ii]['tag'];
  95. tagLinkOutput += "<a href='/#/"+tag+"?q=%23"+tag+"'><strong>"+count+"</strong> #"+tag+"</a>";
  96. }
  97. // console.log(tagLinkOutput);
  98. var menu = "<div class='menu-options' id='tagsMenu'>"+tagLinkOutput+"</div>";
  99. jQ('#savedViewHUDButton').after("<div class='showCompletedButton button'><div class='topBarButtonTextContainer'><a href='#' class='button' id='openTags'>View Tags</a></div></div>"+menu);
  100. jQ('#openTags').click(function() {jQ('#tagsMenu').slideToggle()});
  101. search.searchProjectTree(currentSearch);
  102. };
  103.  
  104. // search.searchProjectTree('#daily-teeth');
  105. // var total = $('.contentMatch').size()/2;
  106. // search.searchProjectTree('#daily-teeth is:complete');
  107. // var done = $('.contentMatch').size()/2;
  108. // console.log(total,done);
  109. // console.log(done/total);
  110. // var pct = done/total;
  111.  
  112. var attemptTags = function() {
  113. setTimeout(function() {
  114. try {
  115. console.log('Generate tags');
  116. generateTagsMenu();
  117. } catch(e) {
  118. console.log("Got exception",e);
  119. attemptTags();
  120. }
  121. },500);
  122. };
  123.  
  124. attemptTags();
  125.  
  126. // Add -rand functionality
  127. jQ(window).on('hashchange',function(e) {
  128. if (searching) {
  129. return false;
  130. }
  131.  
  132. var query = jQ('#searchBox').val();
  133. var needle=/(%23\w*-rand)+/;
  134. var match = window.location.href.match(needle);
  135. if (match) {
  136. // A tag with -rand on the end has been clicked. Locate another.
  137. searching = true;
  138. var tag = match[0]; //matches "2 chapters"
  139. tag = "#"+tag.slice(3);
  140. window.location.href='/#';
  141. search.searchProjectTree(tag);
  142. var target = null;
  143. var count = 0;
  144. var tags = $('.contentMatch');
  145. var random = $(tags[Math.floor(Math.random()*tags.length)])[0];
  146. var parent = jQ(random).parents('.name').find('a').first();
  147. var href = jQ(parent).attr('href');
  148. window.location.href = href;
  149. setTimeout(function() {
  150. searching = false;
  151. },100);
  152. }
  153. });
  154.  
  155.  
  156. // Add styles
  157. jQ('body').append("<style>#tagsMenu{max-width: 300px; right: 140px;}#tagsMenu a {margin: 0 5px; display: block; float: left;}</style>");
  158. }
  159.  
  160. // load jQuery and execute the main function
  161. addJQuery(main);