Feedly: partial refresh by R in any keyboard layout

Refresh by "R" in any national keyboard layout, add styles, date of refresh and floating title of opened article

  1. // ==UserScript==
  2. // @id feedlyCtrlF5
  3. // @name Feedly: partial refresh by R in any keyboard layout
  4. // @name:ru Feedly: обновление списка по R в любом регистре
  5. // @version 14.2017.11.8
  6. // @description Refresh by "R" in any national keyboard layout, add styles, date of refresh and floating title of opened article
  7. // @description:ru Обновляет по "R", исправляет стили, добавляет время обновления и висячий заголовок открытой статьи
  8. // @namespace github.com/spmbt
  9. // @include http://feedly.com/*
  10. // @include https://feedly.com/*
  11. // @update 12 hide #popupPart
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. //(en) In the site feedly.com there are many keyboard shortcuts, for example, "R" - is "Refresh" of part of page, renewing of list of records. Unfortunately, there is bug in any national keyboard layout. It catch keyboard letter, but not key code. Script fix it and add such partial refresh by Ctrl-F5 or Shift-F5.
  16.  
  17. //Userstyles added to script as bonus. Styles make table more compact and remove unneeded buttons such as Twitter etc. It may to disable userstyles by CSS_ON =0.
  18.  
  19. // Additions of 20, Oct 2014:
  20. // * show date-time of page loading or partial refresh by "R").
  21. // * author and title in floating block on top;
  22. // * styles fixing
  23.  
  24. //(ru) На сайте feedly.com есть много клавиатурных сокращений, в частности, R - это "Refresh" части страницы, а именно - обновление списка записей. К сожалению, есть недоработка: в иной национальной раскладке клавиша перестаёт действовать. Ловится клавиша не по ней самой, а по символу на ней. Расширение исправляет недоработку. И добавляет возможность частичного обновления по Ctrl-F5 или Shift-F5. конечно, не мешало бы добавить и исправление этого недостатка для других клавиш, если ими пользуются.
  25.  
  26. //Как бонус, добавляются стили, относящиеся к сайту, чтобы не добавлять их в юзер-стилях. Делают таблицу компактнее и убирают лишние кнопки (Твиттер и прочие). Отключить стили можно переменной CSS_ON в скрипте, установов в 0.
  27.  
  28. (function(userCss){
  29. var CSS_ON =1; //user CSS enable
  30.  
  31. var win = typeof unsafeWindow !='undefined'? unsafeWindow : (function(){return this})()
  32. ,wcl = win.console.log
  33. ,$q = function(q, el){return (el||document).querySelector(q)}
  34. ,ff
  35. ,Tout = function(h){
  36. (function(){
  37. if((h.dat = h.check(h.t) )) //wait of positive result, then occcurense
  38. h.occur();
  39. else if(h.i-- >0) //next slower step
  40. win.setTimeout(arguments.callee, (h.t *= h.m) );
  41. })();
  42. }, tOuttime;
  43. new Tout({t:320, i:7, m: 1.6
  44. ,check: function(){
  45. return document && $q('#pageActionRefresh');
  46. }
  47. ,occur: function(){
  48. var $flBarL, $flBarR, $timeFloat = document.createElement('div');
  49. document.addEventListener('keydown',ff = function(ev){
  50. var refroButt = $q('#pageActionRefresh')
  51. ,key = ev.keyCode || ev.which;
  52. //wcl(4, ev.keyCode, ev.which, ev.type)
  53. if(key ==82 || key ==116 && (ev.ctrlKey || ev.shiftKey) ){
  54. refroButt.click();
  55. var t = ev.target;
  56. while(t.tagName !='INPUT' && t.tagName !='TEXTAREA' && t.tagName !=null)
  57. t = t.parentNode;
  58. if(t.tagName !='INPUT' && t.tagName !='TEXTAREA' ){
  59. win.setTimeout(function(){new Tout(tOuttime)}, 900);
  60. ev.preventDefault();}}
  61. ev.stopPropagation();
  62. },!1);
  63. new Tout(tOuttime = {t:520, i:6, m: 1.6
  64. ,check: function(){
  65. return $q('.header.row .extra >.actions-and-details-container');
  66. },occur: function($){
  67. $flBarR = $q('#headerBarFX div.right-col');
  68. $flBarL = $q('#headerBarFX .header.row h1');
  69.  
  70. var NOW = new Date(), NOWmins = NOW.getMinutes()
  71. ,now ='<i class="timeFloat">'+NOW.getFullYear() +'-'+ (NOW.getMonth() +1) +'-'+ NOW.getDate() +', '+ NOW.getHours() +':'+ (NOWmins>9?'':0) + NOWmins +'</i>';
  72. (!$ && this.dat || $.parentNode).insertAdjacentHTML('beforeend', now);
  73.  
  74. if($flBarL && !$q('.title', $flBarL))
  75. $flBarL.insertAdjacentHTML('beforeend','<div class="lineTitleFloat"><span class=author title=""></span> <b class=title></b></div>');
  76. }
  77. });
  78. document.addEventListener('keyup',ff);
  79. setInterval(function(){
  80. var $inFrm = $q('.inlineFrame');
  81. $flBarR = $q('#headerBarFX div.right-col');
  82. $flBarL = $q('#headerBarFX .header.row h1');
  83. $pgBarR = $q('#feedlyPageFX div.right-col');
  84. if($flBarL && !$q('.title', $flBarL))
  85. $flBarL.insertAdjacentHTML('beforeend','<div class="lineTitleFloat"><span class=author title=""></span> <b class=title></b></div>');
  86. if(!$flBarL) return;
  87. NOW = new Date(), NOWmins = NOW.getMinutes()
  88. ,now ='<i class="timeFloat">'+NOW.getFullYear() +'-'+ (NOW.getMonth() +1) +'-'+ NOW.getDate() +', '+ NOW.getHours() +':'+ (NOWmins>9?'':0) + NOWmins +'</i>';
  89. if($flBarR && !$q('.timeFloat', $flBarR)){
  90. $flBarR.insertAdjacentHTML('beforeend', now);}
  91. if($pgBarR && !$q('.timeFloat', $pgBarR)){
  92. $pgBarR.insertAdjacentHTML('beforeend', now);}
  93. if($inFrm)
  94. var author = $q('.metadata .sourceTitle', $inFrm)
  95. ,title = $q('.entryHeader .title', $inFrm);
  96. var $timeHead = $q('.timeFloat');
  97. //wcl(13, $q('.author', $flBarL), $q('.title', $flBarL), $timeFloat && $timeHead && $timeHead.innerHTML =='','\n')
  98. if($timeFloat && $timeHead && $timeHead.innerHTML =='')
  99. tOuttime.occur($timeHead);
  100. $q('.author', $flBarL).innerHTML = author && author.innerHTML ||'';
  101. $q('.author', $flBarL).title = author && author.innerHTML ||'';
  102. $q('.title', $flBarL).innerHTML = title && title.innerHTML ||'';
  103. document.title = ((author && author.innerHTML ||'') +(author || title ?' / ':'')+ (title && title.innerHTML ||'')).replace(/&nbsp;/,' ') || !author && !title && $q('#headerBarFX .header').innerText;
  104. }, 999);
  105. }
  106. });
  107. (function(css){ //addRules
  108. if(typeof addStyle !='undefined') addStyle(css);
  109. else{
  110. var heads = document.getElementsByTagName('head'), node = document.createElement('style');
  111. node.type ='text/css';
  112. node.appendChild(document.createTextNode(css));
  113. heads[0] && heads[0].appendChild(node);
  114. }
  115. })('body{overflow:auto!important}#notifications{display:none!important}'
  116. +'#headerBarFX,.floatingBar{height: auto; padding:0 0 4px; background: #f8f8f8}'
  117. +'#headerBarFX{margin-left:-41px}'
  118. +'.pageActionBar{height: 18px!important}'
  119. +'#headerBarFX .pageActionBar{margin-right: 145px}'
  120. +'#section0 .label >div{height: 1.3em!important; text-align: right; font-size: 11px; font-style: italic; color: #a3a3a2}'
  121. +'.lineTitleFloat{line-height: 16px; margin:0 -70px -1px -6px; padding:0 3px; border-bottom: 2px solid #f8f8f8;font-weight:normal}'
  122. +'.header.row .timeFloat{position: absolute; display: block; right: 25px; bottom: -.5em; color: #a3a3a2;}'
  123. +'#searchBarFX{height: auto; padding: 4px 0;}'
  124. +'#searchBarFX button.pro{width: 7px; min-width:7px; opacity:.24;}'
  125. +'#searchBarFX button.pro:hover{width: auto;}'
  126. +'.fx .button.primary.pro, .fx button.primary.pro, .fx-button.primary.pro{left:-34px; background-color: #ecc}'
  127. +'.lineTitleFloat .author{display: inline-block; float: left; min-width: 87px; padding-right: 1em; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; font-size: 13px;}.lineTitleFloat .title{font-size: 13px;}'
  128. +'#headerBarFX.title-only header{padding-right:5px; padding-left:1px}'
  129. +'#headerBarFX h1{align-items: normal}'
  130. +'.timeFloat{float: right; line-height: 18px; margin: 0 -28px 0 -18px; color: #a3a3a2}'
  131. + (CSS_ON? userCss :'') );
  132.  
  133. })(
  134. ' #feedlyTabsHolder{width: 240px!important}'
  135. +'#feedlyTabs{padding: 0 2px 0 0!important}'
  136. +'#mainBarFX{margin: 0 0 0 -42px; padding: 24px 0}'
  137. +'#mainBar, #feedlyPage{width:auto!important}'
  138. +'#feedlyPageFX{padding: 0 10px 0 12px}'
  139. +'#feedlyPageFX.title-only, #searchBarFX.title-only .container{padding: 0 18px 0 11px}'
  140. +'a[style*="images/condensed-twitter-black"], a[style*="images/condensed-sharing-facebook"]{display:none!important}'
  141. +'#feedlyMessageBar, .feedly-logo, #popupPart{display:none!important}'
  142. +'.profileMore{margin-right:38px!important}'
  143. +'#feedlyTitleBar{margin-left: 11px!important}'
  144. +'#feedlyPart0{padding-left: 6px!important}'
  145. +'.fx button.full-width, .fx-button.full-width{width:94%}'
  146. +'#feedlyPart{padding-right: 6px!important}'
  147. +'.u0Entry .condensedTools{width: auto!important}'
  148. +'.u0Entry .condensedTools img {padding:0!important}'
  149. +'.u0Entry .condensedTools a:first-child{margin: 0 -5px 0 6px}'
  150. +'.u0Entry .lastModified{padding-left: 2px!important}'
  151. +'.u0EntryList{margin-top: 0!important}'
  152. +'.u100Entry .title{font-size:16px!important}'
  153. +'.u100Frame .u100Entry .title, .inlineFrame .u100Entry .title{margin-bottom: 1rem!important; line-height: 1.2rem!important}'
  154. +'.u100Frame .u100Entry .title:hover, .inlineFrame .u100Entry .title:hover, .entryholder .fx-button.secondary.visitWebsiteButton:hover{background-color: #f8f8f8!important}'
  155. +'.pinContainer span{opacity:0!important}'
  156. +'.list-entries .inlineFrame{padding: 20px 10px 18px 12px}'
  157. +'.visitWebsiteButton, .tagsHolder{margin-top:-8px!important}.visitWebsiteButton{padding: 4px 0 2px; border: 1px solid #f4f4f4!important}'
  158. +'.frameActionsTop{height: 18px!important; line-height: 20px!important; margin-top:-20px!important}'
  159. +'.entryholder{padding-bottom: 0.5rem!important}'
  160. +'.websiteCallForAction, .secondaryCallForAction{margin-top: 20px!important}'
  161. +'.slabserif .entryBody{font-family: "Verdana","Slab Serif",Helvetica,sans-serif!important; font-size: 14px; line-height: 1.5em!important;}'
  162. );

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址