unity

hkgalden utilities

  1. // ==UserScript==
  2. // @name unity
  3. // @version 0.4.1
  4. // @description hkgalden utilities
  5. // @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
  6. // @include http://*hkgalden.com/*
  7. // @namespace hkga unity
  8. // @copyright ignite
  9. // ==/UserScript==
  10. (function(W, D, G, $, $$){
  11. 'use strict';
  12. $ = W.$;
  13. $.fn.findAtDepth = function(selector, maxDepth){
  14. var depths = [], i;
  15. if(maxDepth > 0){
  16. for(i = 1; i <= maxDepth; i++) depths.push('> ' + new Array(i).join('* > ') + selector);
  17. selector = depths.join(', ');
  18. }
  19. return this.find(selector);
  20. };
  21. $$ = function(q){return D.querySelectorAll(q)};
  22. if(!G.GM_getValue || (G.GM_getValue.toString && G.GM_getValue.toString().indexOf("not supported") > -1)){
  23. G.GM_getValue=function(key,def){return localStorage[key] || def;};
  24. G.GM_setValue=function (key,value){return localStorage[key]=value;};
  25. G.GM_deleteValue=function (key) {return delete localStorage[key];};
  26. }
  27. var CHKBX_OPTS = ['nextPageHideAuthor', 'lessQuote', 'clickToShowPics', 'adBlock'],
  28. CHKBX_OPTS_TITLE = {
  29. nextPageHideAuthor: '只在第一頁顯示 #0',
  30. lessQuote: '限制Quote數量',
  31. clickToShowPics: '不自動載入圖片',
  32. adBlock: '移除廣告'
  33. },
  34. CFG = {};
  35. for(var i = 0, l = CHKBX_OPTS.length; i < l; i++){
  36. CFG[CHKBX_OPTS[i]] = G.GM_getValue(CHKBX_OPTS[i], false);
  37. }
  38. var API = {}, _exec;
  39. API.isLoggedIn = $$('#gb .actp a[href="/my"]').length;
  40. // topics
  41. _exec = /\/[A-Za-z]{2}\/(\d+)/.exec(location.href);
  42. API.topics = {};
  43. API.topics.is = location.href.indexOf('topics/') > 0;
  44. API.topics.page = API.topics.is ? _exec ? +_exec[1] : 1 : 0;
  45. // view
  46. _exec = /\/page\/(\d+)/.exec(location.href);
  47. API.view = {};
  48. API.view.is = location.href.indexOf('view/') > 0;
  49. API.view.page = API.view.is ? _exec ? +_exec[1] : 1 : 0;
  50. API.view.author = API.view.is ? $$('.gpt.author .dtl>.unm>.name')[0].innerHTML : null;
  51. // insert config panel
  52. var panel = $('<a/>', {
  53. href:'#',
  54. text:'unity',
  55. }).on('click', function(e){
  56. e.preventDefault();
  57. $('body').append('<div id="unity--panel" style="background:rgba(0,0,0,.4);height:100%;left:0;position:absolute;top:'+D.body.scrollTop+'px;width:100%;z-index:999999">\
  58. <div style="display:table;height:100%;width:100%">\
  59. <div style="display:table-cell;height:100%;vertical-align: middle;width:100%">\
  60. <div id="unity--config"></div>\
  61. </div>\
  62. </div>\
  63. </div>').css({overflow:'hidden'});
  64. var chkbxes = '<table class="nxtb" style="background:#cec;width:540px">';
  65. for(var i = 0, l = CHKBX_OPTS.length; i < l; i++){
  66. chkbxes += '<tr><td>'+CHKBX_OPTS_TITLE[CHKBX_OPTS[i]]+'</td><td><input id="'+CHKBX_OPTS[i]+'" type="checkbox"'+(G.GM_getValue(CHKBX_OPTS[i]) ? ' checked' : '')+'></td>';
  67. }
  68. chkbxes += '</table>';
  69. $('#unity--config').append([
  70. $('<h2 style="background:#fe5;border-radius:50%;cursor:pointer;font-weight:700;line-height:64px;margin:0;position:absolute;right:24px;top:24px;width:64px;">×</h2>').on('click', function(){
  71. $(D).off('.unity');
  72. $('#unity--panel').remove();
  73. $('body').css({overflow:'auto'});
  74. }),
  75. chkbxes,
  76. '<br>',
  77. $('<button style="background:#eee;border-radius:50%;height:64px;margin:32px 0;width:64px">確認</button>').on('click', function(){
  78. location.reload();
  79. })
  80. ]);
  81. $(D).on('change.unity', '#unity--config :checkbox', function(){
  82. G.GM_setValue(this.getAttribute('id'), this.checked);
  83. });
  84. });
  85. panel.insertBefore('#gb .actp :first-child');
  86. // mod
  87. var DOMwatcher = function(root, callback){
  88. var __appendChild = document.body.appendChild,
  89. patch = function(node){
  90. if(typeof node.appendChild !== 'undefined' && node.nodeName !== '#text'){
  91. node.appendChild = function(incomingNode){
  92. callback(node, incomingNode);
  93. patch(incomingNode);
  94. walk(incomingNode);
  95. __appendChild.call(node, incomingNode);
  96. };
  97. }
  98. walk(node);
  99. },
  100. walk = function(node){
  101. var i = node.childNodes.length;
  102. while(i--) patch(node.childNodes[i]);
  103. };
  104. patch(root);
  105. };
  106. if(API.view.is){
  107. if(CFG.nextPageHideAuthor && API.view.page > 1){
  108. var ctn = $('.gpt.author>.r>.ctn');
  109. ctn.hide().after($('<div class="ctn"><a href="#" style="color:#499">按此顯示 #0</a></div>').on('click',function(e){
  110. e.preventDefault();
  111. $(this).remove() && ctn.show();
  112. }));
  113. }
  114. var hideQuotes = function(){
  115. if(!CFG.lessQuote) return;
  116. $.each($$('.gpt>.r>.ctn'), function(i, e){
  117. var d = $(e).findAtDepth('blockquote:not(.united)', 3), b;
  118. if(d.length === 3){
  119. b = $(d[2]);
  120. b.hide().addClass('united');
  121. $('<blockquote class="united" style="background:#cea;color:#000;cursor:pointer;display:inline-block;margin-bottom:24px">顯示更多引用回覆</blockquote>').on('click',function(){
  122. b.show();
  123. $(this).remove();
  124. }).insertAfter(b);
  125. }
  126. });
  127. },
  128. hidePics = function(){
  129. if(!CFG.clickToShowPics) return;
  130. $('body').css({overflow:'hidden'});
  131. $.each($$('.gpt>.r>.ctn img[data-original]'), function(i, e){
  132. var i = $('<img alt src="'+this.getAttribute('data-original')+'" style="display:none">');
  133. i.on('load', function(){
  134. if(i[0].width > 72 && i[0].height > 72){
  135. i.parent().after($('<div class="ico" style="cursor:pointer;display:inline-block;font-size:48px;height:48px;line-height:48px;text-align:center;width:48px;"></div>').on('click',function(e){
  136. $(this).remove() && i.show();
  137. }));
  138. }else i.show();
  139. });
  140. $(this).replaceWith(i);
  141. });
  142. $('body').css({overflow:'auto'});
  143. },
  144. adBlock = function(){
  145. if(!CFG.adBlock) return;
  146. $('.gpt>.r .ad').prev('hr').andSelf().add('.gpt>.r .aderfly-ad').remove();
  147. $('#main~.adContainer,header~.adContainer').remove();
  148. };
  149. hideQuotes();
  150. hidePics();
  151. adBlock();
  152. $(D).on('DOMNodeInserted', '#main>article', function(e){
  153. if(e.target.className.indexOf('replies') > 0){
  154. hideQuotes();
  155. hidePics();
  156. adBlock();
  157. }
  158. });
  159. }
  160. })(unsafeWindow, document, this);