Feedly Scroll Marker

Display the marker of page scroll in Feedly. / Feedlyでページスクロールしたときにマーカーを表示します。

当前为 2014-05-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Feedly Scroll Marker
  3. // @description Display the marker of page scroll in Feedly. / Feedlyでページスクロールしたときにマーカーを表示します。
  4. // @id FeedlyScrollMarker
  5. // @namespace http://userscripts.org/scripts/show/174679
  6. // @homepage https://userscripts.org/scripts/show/174679
  7. // @include http://feedly.com/*
  8. // @include https://feedly.com/*
  9. // @version 1.02
  10. // @grant GM_addStyle
  11. // ==/UserScript==
  12.  
  13. (function() {
  14.  
  15. try { if (typeof localStorage !== 'object') return alert('FSM Error: DOM Storage'); }
  16. catch(er) { return alert('FSM Error: DOM Storage'); }
  17. var $id = function(id) { return document.getElementById(id); }, iInit;
  18.  
  19. var init = function() {
  20. var nScrPos = 0, nTime = 750, shift = false, iMarker, st;
  21. var ism = document.createElement('div');
  22. ism.id = 'fsm_scroll_marker';
  23. document.body.appendChild(ism);
  24. var CSS = [
  25. '#fsm_settings { display: none; color: black; position: absolute; top: 68px; left: 68px; z-index: 90200; background: rgba(255, 255, 255, 0.98); border: 1px solid #999999; border-radius: 4px; min-width: 35em; box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); }',
  26. '#fsm_s_titlebar { background-color: #666666; border-radius: 4px 4px 0 0; padding: 2px 0 0 4px; height: 2em; }',
  27. '#fsm_s_title a { font-size: 110%; font-weight: bold; color: white; text-decoration: none; }',
  28. '#fsm_s_title a:hover { color: #FFFF99; }',
  29. '#fsm_s_btn { position: absolute; top: 2px; right: 4px; }',
  30. '#fsm_s_ok { margin-right: 0.5em; padding: 0 2em; }',
  31. '#fsm_s_cancel { padding: 0 1ex; }',
  32. '#fsm_s_ok, #fsm_s_cancel { font-size: 80%; }',
  33. '#fsm_s_body { padding: 0.5em 1em; }',
  34. '#fsm_s_body fieldset { margin: 4px 2px; background: rgba(255, 255, 255, 0); }',
  35. '#fsm_s_body input { margin-left: 0.5em; text-align: center; width: 6ex; }',
  36. '#fsm_s_body input[type="checkbox"] { vertical-align: middle; width: auto; }',
  37. '#fsm_s_time { vertical-align: inherit; }',
  38. '#fsm_scroll_marker { position: absolute; width: 100%; height: 4px; margin-top: -2px; background: rgba(255,0,0,0.25); display: none; z-index: 88800; }'
  39. ].join('');
  40. GM_addStyle(CSS);
  41. var locale_ja = [
  42. '設定',
  43. 'キャンセル',
  44. 'マーカーを表示する時間 (ミリ秒):',
  45. 'マーカーを表示するショートカットキー'
  46. ];
  47. var locale_en = [
  48. 'Settings',
  49. 'Cancel',
  50. 'Time to display the marker (msec):',
  51. 'Keyboard shortcut to display the marker'
  52. ];
  53. var loc = (window.navigator.language === 'ja') ? locale_ja : locale_en;
  54. var currentEntry = function() {
  55. var t1 = 'pageActionLayout', t2 = 'pageLayoutAction selected';
  56. var fo = ($id(t1 + '0').className === t2) ? 'T'
  57. : ($id(t1 + '4').className === t2) ? 'M'
  58. : ($id(t1 + '6').className === t2) ? 'C'
  59. : ($id(t1 + '100').className === t2) ? 'F' : '';
  60. switch (fo) {
  61. case 'T': case 'M': case 'C':
  62. return document.evaluate('id("timeline")//div[contains(concat(" ", @class, " "), " inlineFrame ")]', document, null, 9, null).singleNodeValue;
  63. case 'F':
  64. return document.evaluate('id("timeline")//div[contains(concat(" ", @class, " "), " selectedEntry ")]', document, null, 9, null).singleNodeValue;
  65. default:
  66. return document.evaluate('id("mainArea")//div[contains(concat(" ", @class, " "), " inlineFrame ")]', document, null, 9, null).singleNodeValue;
  67. }
  68. };
  69. var viewSettings = function() {
  70. if ($id('fsm_settings').style.display === 'block') {
  71. $id('fsm_settings').style.display = 'none';
  72. return;
  73. }
  74. $id('fsm_s_time').value = st.time;
  75. $id('fsm_s_key_page').checked = (st.key_page) ? true : false;
  76. $id('fsm_s_key_space').checked = (st.key_space) ? true : false;
  77. $id('fsm_settings').style.display = 'block';
  78. };
  79. var loadSettings = function() {
  80. st = {};
  81. try {
  82. st = JSON.parse(localStorage.getItem('FeedlyScrollMarker_settings')) || {};
  83. } catch(er) { alert('FSM Error: Load Settings'); }
  84. var notB = function(a) {
  85. return (typeof a !== 'boolean') ? true : false;
  86. };
  87. var notN = function(a) {
  88. return (typeof a !== 'number') ? true : false;
  89. };
  90. if (notN(st.time)) st.time = nTime;
  91. if (notB(st.key_page)) st.key_page = true;
  92. if (notB(st.key_space)) st.key_space = true;
  93. };
  94. var saveSettings = function() {
  95. try {
  96. localStorage.setItem('FeedlyScrollMarker_settings', JSON.stringify(st));
  97. } catch(er) { alert('FSM Error: Save Settings'); }
  98. };
  99. var div = document.createElement('div');
  100. div.id = 'fsm_settings';
  101. document.body.appendChild(div);
  102. $id('fsm_settings').innerHTML = '<div id="fsm_s_titlebar"><div id="fsm_s_title"><a href="https://userscripts.org/scripts/show/174679" target="_blank">Feedly Scroll Marker ' + loc[0] + '</a></div><div id="fsm_s_btn"><input type="button" id="fsm_s_ok" value="OK"><input type="button" id="fsm_s_cancel" value="' + loc[1] + '"></div></div><div id="fsm_s_body"><label>' + loc[2] + '<input id="fsm_s_time" type="text" maxlength="4"></label><fieldset><legend>' + loc[3] + ' : </legend><label><input id="fsm_s_key_page" type="checkbox">PageUp / PageDown</label><br><label><input id="fsm_s_key_space" type="checkbox">Space / Shift+Space</label></fieldset></div>';
  103. if ($id('feedlyTabs')) {
  104. var div1 = document.evaluate('id("feedlyTabs")/div[2]/div[@style="margin-top:32px; margin-bottom:32px"]', document, null, 9, null).singleNodeValue;
  105. if (div1) {
  106. var div2 = document.createElement('div');
  107. div2.className = 'tab';
  108. div2.innerHTML = '<div class="header target"><div id="fsm_settings-menu" style="color:inherit; padding-left:32px;" target="new" class="label">Scroll Marker ' + loc[0] + '</div></div>';
  109. window.setTimeout(function() {
  110. div1.appendChild(div2);
  111. }, 1500);
  112. }
  113. }
  114. document.addEventListener('keydown', function(e) {
  115. if (!/^input|^textarea/i.test(e.target.tagName) && st.time !== 0) {
  116. if (
  117. (st.key_page && e.keyCode === 33) ||
  118. (st.key_page && e.keyCode === 34) ||
  119. (st.key_space && e.keyCode === 32)
  120. ) {
  121. ism.style.display = 'none';
  122. nScrPos = document.body.scrollTop;
  123. if (e.shiftKey) shift = true;
  124. } else if (e.keyCode === 13) {
  125. if (currentEntry()) {
  126. window.clearTimeout(iMarker);
  127. ism.style.display = 'none';
  128. }
  129. } else if (ism.style.display !== 'none') {
  130. window.clearTimeout(iMarker);
  131. ism.style.display = 'none';
  132. }
  133. }
  134. }, true);
  135. document.addEventListener('keyup', function(e) {
  136. if (!/^input|^textarea/i.test(e.target.tagName) && st.time !== 0) {
  137. var sch = document.body.clientHeight;
  138. var sst = document.body.scrollTop;
  139. if (
  140. (st.key_page && e.keyCode === 33) ||
  141. (st.key_space && e.keyCode === 32 && e.shiftKey)
  142. ) {
  143. if (nScrPos !== sst) {
  144. ism.style.display = 'block';
  145. ism.style.top = (nScrPos - (ism.scrollHeight / 2)) + 'px';
  146. window.clearTimeout(iMarker);
  147. if (st.time > 0) {
  148. iMarker = window.setTimeout(function() {
  149. window.clearTimeout(iMarker);
  150. ism.style.display = 'none';
  151. }, st.time);
  152. }
  153. }
  154. shift = false;
  155. } else if (
  156. (st.key_page && e.keyCode === 34) ||
  157. (st.key_space && e.keyCode === 32 && !e.shiftKey)
  158. ) {
  159. if (nScrPos !== sst) {
  160. ism.style.display = 'block';
  161. ism.style.top = (nScrPos + sch + (ism.scrollHeight / 2)) + 'px';
  162. window.clearTimeout(iMarker);
  163. if (st.time > 0) {
  164. iMarker = window.setTimeout(function() {
  165. window.clearTimeout(iMarker);
  166. ism.style.display = 'none';
  167. }, st.time);
  168. }
  169. }
  170. shift = false;
  171. }
  172. }
  173. }, true);
  174. document.addEventListener('click', function(e) {
  175. if (e.button >= 2) return;
  176. if (e.target.id === 'fsm_settings-menu') {
  177. viewSettings();
  178. } else if (e.target.id === 'fsm_s_ok') {
  179. var time = $id('fsm_s_time').value, problem = false;
  180. if (time === '' || /^\s+$/.test(time)) st.time = nTime;
  181. else if (time && !isNaN(time)) st.time = Number(time);
  182. else problem = true;
  183. if (!problem) {
  184. st.key_page = $id('fsm_s_key_page').checked;
  185. st.key_space = $id('fsm_s_key_space').checked;
  186. $id('fsm_s_ok').blur();
  187. $id('fsm_settings').style.display = 'none';
  188. saveSettings();
  189. }
  190. } else if (e.target.id === 'fsm_s_cancel') {
  191. $id('fsm_s_cancel').blur();
  192. $id('fsm_settings').style.display = 'none';
  193. } else if (ism.style.display !== 'none') {
  194. window.clearTimeout(iMarker);
  195. ism.style.display = 'none';
  196. }
  197. }, false);
  198. loadSettings();
  199. };
  200.  
  201. iInit = window.setInterval(function() {
  202. if ($id('feedlyPage') && $id('pageActionRefresh')) {
  203. window.clearInterval(iInit);
  204. window.setTimeout(function() {
  205. init();
  206. }, 1000);
  207. }
  208. }, 500);
  209.  
  210. })();

QingJ © 2025

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