exmail.qq.com_view_plus

自制邮件聚合模式,吊打会话模式,让脚本改变世界(已支持腾讯企业邮箱)

  1. // ==UserScript==
  2. // @name exmail.qq.com_view_plus
  3. // @description 自制邮件聚合模式,吊打会话模式,让脚本改变世界(已支持腾讯企业邮箱)
  4. // @version 1.92
  5. // @namespace https://wanyaxing.com/blog/20190120150811.html
  6. // @author wyx@wanyaxing.com
  7. // @include https://exmail.qq.com/cgi-bin/mail_list*
  8. // @run-at document-body
  9. // ==/UserScript==
  10.  
  11. // 腾讯企业邮箱-聚合模式
  12. if (document.getElementById('frm')) {
  13. document.getElementById('frm').style.display='none';
  14. function selectText(element) {
  15. var selection = window.getSelection();
  16. selection.setBaseAndExtent(element, 0, element, 1);
  17. }
  18.  
  19. function watchTdTime(_this, tdTime) {
  20. if (!tdTime)
  21. {
  22. var str = _this.innerText;
  23. if (str.indexOf('前')>0) {
  24. var num = parseInt((str.replace(/^(\d+?)[^\d]*$/,'$1'))) * 1000;
  25. if (str.indexOf('分钟前')>0) {
  26. num = num * 60;
  27. } else if (str.indexOf('小时前')>0) {
  28. num = num * 60 * 60;
  29. }
  30. var now = (new Date()).getTime();
  31. tdTime = now - num;
  32. }
  33. }
  34. if (tdTime) {
  35. var time_now = new Date();
  36. var t_over = time_now-tdTime ;
  37. var timelabel,nextTime;
  38. if (t_over>24*60*60000) {
  39. timelabel = (parseInt(t_over/60/60000/24))+'天'+parseInt((t_over-parseInt(t_over/60/60000/24)*60*24*60000)/60/60000)+'小时前';
  40. } else if (t_over>=60*60000) {
  41. timelabel = (parseInt(t_over/60/60000))+'小时前';
  42. } else if (t_over>60000) {
  43. timelabel = parseInt(t_over/60000)+'分钟前';
  44. nextTime = 60000;
  45. }else {
  46. timelabel = parseInt(t_over/1000)+'秒前';
  47. nextTime = 1000;
  48. }
  49. _this.innerHTML = '<div>'+timelabel+'</div>';
  50. if (nextTime) {
  51. // console.log(nextTime,_this.innerHTML);
  52. setTimeout(function(){
  53. watchTdTime(_this, tdTime)
  54. },nextTime);
  55. }
  56. }
  57. }
  58.  
  59. function resetAsStoryLines() {
  60. var graytipNode = document.querySelector('.graytip');
  61. if (graytipNode && graytipNode.innerText.indexOf('会话模式')>=0) {
  62. graytipNode.style.cssText = 'display:none;'
  63. }
  64.  
  65. // 时间表头迁移
  66. var timeTd = document.querySelector('#frm table').querySelector('tr').lastChild.previousSibling;
  67. timeTd.parentNode.insertBefore(timeTd,timeTd.previousSibling);
  68.  
  69. var items = {};
  70. document.querySelectorAll('#frm .toarea>table').forEach(function(child){
  71. var formNode = child.querySelector('.tl nobr');
  72. var subjectNode = child.querySelector('.gt u');
  73. var descNode = child.querySelector('.txt_hidden>b');
  74. var tagDivNode = child.querySelector('.TagDiv');
  75. if (!(formNode && subjectNode && descNode && tagDivNode)){
  76. return
  77. }
  78.  
  79. var formText = formNode.innerText;
  80. formText = formText.replace(/^[\s::\-]*(.*?)[\s::\-]*$/g,'$1');
  81.  
  82. // 主题提炼(移除辅助词如转发回复啥的
  83. var subjectTitle = subjectNode.innerText;
  84. subjectTitle = subjectTitle.replace(/(Re|转发|Fw|回复|发信方已撤回邮件)[:: ]*/g,'');
  85. subjectTitle = subjectTitle.replace(/(\d+-\d+-\d+|\d+\/\d+\/\d+|\d+月\d+日)/g,'');
  86. subjectTitle = subjectTitle.replace(/^.{0,5}[::]/g,'');
  87. var subjectText = subjectTitle.replace(/^[【「\[\((]([^)\)\]」】]*?)[)\)\]」】]$/g,'$1');
  88. subjectText = subjectText.replace(/[【「\[\((](.*?)[)\)\]」】]/g,'');
  89. subjectText = subjectText.replace(/^[\s::\-,]*(.*?)[\s::\-]*$/g,'$1');
  90. if (subjectText == '') {
  91. subjectText = subjectTitle?subjectTitle:subjectNode.innerText;
  92. }
  93.  
  94. // 简情处理(移除签名信息等)
  95. var descText = descNode.innerText;
  96. descText = descText.replace(/---+.*/g,'');
  97. descText = descText.replace(/原始邮件\s.*/g,'');
  98. descText = descText.replace(/(From|Sender|发件人)[::].*/g,'');
  99. descText = descText.replace(new RegExp('姓名:'+formText + '\\s.*','g'),'');
  100. descText = descText.replace(/在\s\d+年\d+月\d+日,.*?写道.*/g,'');
  101. descText = descText.replace(/\s[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+\s*$/g,'');
  102. descText = descText.replace(/^[\s::\-]*(.*?)[\s::\-]*$/g,'$1');
  103. descNode.innerHTML = descText;
  104.  
  105.  
  106. // 新窗口打开
  107. child.querySelector('.ci .cir').style.cssText = 'position: absolute;width: 90%;background: none;';
  108. // 时间栏 前移
  109. var dtNode = child.querySelector('.dt');
  110. dtNode.style.cssText = 'color:gray';
  111. dtNode.parentNode.insertBefore(dtNode,dtNode.previousSibling);
  112. watchTdTime(dtNode);//动态更新时间栏
  113.  
  114. if (subjectNode.innerText.indexOf('发信方已撤回邮件:')>=0) {
  115. descNode.innerHTML = subjectNode.innerText;
  116. descNode.style.cssText = 'text-decoration: line-through;';
  117. }
  118.  
  119. if (!items[subjectText]){
  120. subjectNode.innerHTML = subjectText;
  121. child.style.cssText = 'padding-top:36px';
  122. if (tagDivNode.firstChild) {
  123. tagDivNode.insertBefore(subjectNode,tagDivNode.firstChild);
  124. } else {
  125. tagDivNode.appendChild(subjectNode);
  126. }
  127. subjectNode.style.cssText = 'margin: 0 14px;';
  128. child.ondblclick = function(){
  129. selectText(subjectNode);
  130. return false;
  131. }
  132. tagDivNode.style.cssText = 'position: absolute;left: -250px;bottom: 28px;';
  133. tagDivNode.parentNode.style.cssText = 'position: relative;overflow: visible;pointer-events: none;';
  134.  
  135. items[subjectText] = child;
  136. } else {
  137. subjectNode.style.cssText = 'display: none;';
  138. tagDivNode.style.cssText = 'display: none;';
  139. items[subjectText].parentNode.insertBefore(child,items[subjectText].nextSibling);
  140. items[subjectText] = child;
  141. }
  142. formNode.style.cssText = 'float: right;color:gray;';
  143. });
  144. // console.log(items);
  145. document.getElementById('frm').style.display='block';
  146. }
  147.  
  148. document.addEventListener('DOMContentLoaded', resetAsStoryLines, false);
  149.  
  150. }