Y-marker

save/restore webpage scroll Y position

目前为 2014-03-31 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Y-marker
  3. // @namespace trespassersW
  4. // @description save/restore webpage scroll Y position
  5. // @include http://*
  6. // @include https://*
  7. // @include file://*
  8. // @exclude http*://www.google.com/reader/*
  9. // @version 1.2
  10. // @updated 2013-12-12
  11. // @released 2013-12-11
  12. // @run-at document-end
  13. // @grant GM_log
  14. // ==/UserScript==
  15. /* 13-12-13 cosmetics
  16. * 13-12-12 click on msg removes all marks
  17. * 1.1 don't run in editable fields
  18. *
  19. */
  20. (function(){ "use strict";
  21. if(top!=self || !document || !document.body ) return;
  22. var W = typeof unsafeWindow != "undefined" ? unsafeWindow : window;
  23. /* key kombinations to invoke the skript */
  24. var kShift = 1, kCtrl = 2, kAlt = 4, kWin = 8;
  25. var kJump = 0;
  26. var kMark = kAlt;
  27.  
  28. /* sec; 0 to disable; -1 status bar only */
  29. var tipShowtime = 2.2;
  30.  
  31. var kNobs = "-0123456789";
  32. var kKeys = {
  33. 173: 0, 48: 1, 49: 2, 50: 3, 51: 4, 52: 5, 53: 6, 54: 7, 55: 8, 56: 9, 57: 10,
  34. 189: 0, /* chrome, opera caps lock */
  35. 109: 0 /* opera */
  36. };
  37. var minus1="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1";
  38.  
  39. function kNob(k){ return kNobs.charAt(k); }
  40.  
  41. var U=undefined, D=W.document;
  42. function _L(s) { 0 && console.log(s) };
  43.  
  44. var statMsg;
  45. function msg(t,k, y){
  46. statMsg = "";
  47. if(U!==k)
  48. statMsg += "["+kNob(k)+"] ";
  49. if(U!==y)
  50. statMsg += ""+pt(y)+"% ";
  51. statMsg += t+ (noCoo ? "\u2262 ": "");
  52. }
  53.  
  54. var locStor;
  55. var noCoo;
  56. // see SQlite manager -> %FFpath%\webappstore.sqlite -> find -> key -> contains Ym#
  57.  
  58. if(!locStor) try {
  59. locStor = W.localStorage;
  60. locStor.getItem("Ym#");
  61. } catch(e){ locStor =null; };
  62.  
  63. if(!locStor) try {
  64. noCoo="no cookies!!1";
  65. locStor = W.sessionStorage;
  66. locStor.getItem("Ym#");
  67. } catch(e){ locStor =null };
  68.  
  69. if(!locStor && U===W.YmStorage){
  70. noCoo= "cookies are disabled!!!11";
  71. W.YmStorage= {
  72. setItem: function(k,v) {this.s[k]=v},
  73. getItem: function(k) {return this.s[k]? this.s[k]: null},
  74. removeItem: function(k) {this.s[k]=null},
  75. s: {}
  76. };
  77. locStor=W.YmStorage;
  78. }
  79.  
  80. function pt(y) {
  81. try{
  82. y =Math.round(y*1000/(document.body.scrollHeight+1))/10;
  83. }catch(e){console.log("math\n"+e); return -1}
  84. return y;
  85. }
  86.  
  87. var Ym;
  88. var pz;
  89.  
  90. function ldYm(){
  91. var s= locStor.getItem(Ym);
  92. if(!s) s=minus1;
  93. pz=s.split(",")
  94. }
  95.  
  96. function svYm(){
  97. var s=pz.join(",");
  98. locStor.setItem(Ym,s)
  99. }
  100.  
  101. function jumpY(k){
  102. var y=pz[k];
  103. if(y > -1) {
  104. if( y!= scrollY ){
  105. pz[0] = scrollY;
  106. scroll(0,y);
  107. msg("jump",k,y);
  108. }else
  109. msg("here",k,y);
  110. return 1;
  111. }
  112. msg("none",k);
  113. return 0;
  114. }
  115.  
  116. function markY(k){
  117. pz[k]=scrollY;
  118. if(k>=1)
  119. svYm();
  120. msg("mark",k,pz[k]);
  121. return 1;
  122. }
  123.  
  124. var kMap= {16: kShift, 17:kCtrl, 18: kAlt, 91: kWin};
  125. var keyMod=0;
  126. var kkWin= (kMark | kJump) & kWin;
  127.  
  128. function klear(e) {
  129. var k= e.keyCode;
  130. if(!k) return;
  131. var km=kMap[k];
  132. if(km) {
  133. keyMod &= -1 ^ km;
  134. }
  135. }
  136.  
  137. function onKeydown(e) {
  138. var rc=0, k= e.keyCode;
  139. if(!k) return;
  140. // Don't run in input, select, textarea etc.
  141. var E = D.activeElement.tagName.toLowerCase();
  142. if (E == "input" || E == "select" || E == "textarea" ||
  143. (E=D.activeElement.contentEditable) == "true" ||
  144. E == "")
  145. { keyMod = 0; return; }
  146. var km =kMap[k]; // ff doesnt track metaKey. stsuko
  147. if(km) {
  148. keyMod |= km;
  149. if( kkWin && km === kWin ) //???
  150. e.preventDefault(), e.stopPropagation();
  151. return;
  152. }
  153. km=keyMod;
  154. if( U=== (k=kKeys[k]) ){ keyMod = 0; return; }
  155. if( km === kJump ) {
  156. rc = jumpY(k);
  157. }else if( km === kMark ) {
  158. rc = markY(k);
  159. }else {
  160. return;
  161. }
  162. statSay();
  163. if(rc) e.preventDefault(),e.stopPropagation();
  164. }
  165. function mk(p, t, s, h) {
  166. var e = D.createElement(t);
  167. e.style.cssText = s;
  168. p.appendChild(e);
  169. if (h) e.innerHTML = h;
  170. return e
  171. };
  172.  
  173. /* RIP status bar replacement */
  174. var sb = mk(D.body, 'div',
  175. "position: fixed;\
  176. top: 0px; right: 1px; bottom: auto; left: auto;\
  177. background: rgba(221,255,221,.75);\
  178. padding: 2px 3px 2px 8px; margin:0;\
  179. border: none;\
  180. border-radius: 12px 3px 3px 12px; \
  181. color: #131;\
  182. opacity: 1; display: none;\
  183. z-index: 2147483647;\
  184. font: normal 12px/14px sans-serif !important;\
  185. text-shadow: #373 2px 2px 4px, #7F7 -2px -2px 4px;\
  186. cursor:no-drop;\
  187. "
  188. );
  189.  
  190. var tO;
  191. function onTout(){
  192. tO=0; sb.style.display="none";
  193. }
  194. function noTout(){
  195. if(tO) clearTimeout(tO), onTout();
  196. }
  197.  
  198. function statSay(t) {
  199. if(statMsg){
  200. if(tipShowtime)
  201. W.status=statMsg;
  202. if(tipShowtime>0){
  203. noTout();
  204. sb.innerHTML= statMsg;
  205. sb.style.display="block";
  206. tO=setTimeout(onTout, (t? t: tipShowtime)*1000);
  207. }
  208. }
  209. statMsg="";
  210. }
  211.  
  212. Ym="Ym#"+location.pathname;
  213. _L("load: "+location+"\n >> "+Ym);
  214.  
  215. ldYm();
  216. for(var k=1; k<2; k++){ /* pz.length */
  217. if(pz[k]>-1){
  218. scroll(0,pz[k]);
  219. msg('jump',k,pz[k]);
  220. statSay(5);
  221. break;
  222. }
  223. };
  224. /* click removes all */
  225. if(tipShowtime>0){
  226. sb.addEventListener("click",function (e) {
  227. locStor.removeItem(Ym);
  228. ldYm(); noTout();
  229. },false);
  230. };
  231.  
  232. if(noCoo) msg(noCoo), statSay(7);
  233. console.log('xyu');
  234. W.addEventListener("keydown",onKeydown,false);
  235. W.addEventListener("keyup",klear,false);
  236. })();