Guest User

Untitled

a guest
Jun 2nd, 2020
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.10 KB | None | 0 0
  1. // ==UserScript==
  2. // @name tabProtect_mod2.uc.js
  3. // @namespace http://space.geocities.yahoo.co.jp/gl/alice0775
  4. // @description tabProtect
  5. // @include main
  6. // @exclude about:*
  7. // @author Alice0775
  8. // @Note タブのデタッチ非対応
  9. // @Note タスクバーからprivate browsingモードに入るとtabの状態と復帰後のtabのセッション保存おかしくなる
  10. // @compatibility 69
  11. // @version 2019/05/29 16:00 Bug 1519514 - Convert tab bindings
  12. // @version 2019/05/21 08:30 fix 69.0a1 Bug 1551320 - Replace all createElement calls in XUL documents with createXULElement
  13. // @version 2018/09/27 10:30 fix tab detach
  14. // @version 2018/09/26 07:30 support tab detach
  15. // @version 2018/09/25 21:30 working with tab multi selection
  16. // @version 2018/06/21 19:50 workaround regression
  17. // @version 2018/06/21 19:40 fix restore session if *.restore_on_demand is enabled
  18. // @version 2018/06/10 00:00 workaround restore session
  19. // @version 2018/05/23 00:00 Fixed typo(status is undeled when unprotect)
  20. // @version 2018/05/12 15:30 workaround restore session for all window
  21. // @version 2018/05/06 14:00 workaround for tab move
  22. // @version 2018/05/04 12:00 cleanup for 60
  23. // @version 2018/05/04 23:00 for 60
  24. // ==/UserScript==
  25.  
  26. var tabProtect = {
  27. debug: function(aMsg){
  28. Cc["@mozilla.org/consoleservice;1"]
  29. .getService(Ci.nsIConsoleService)
  30. .logStringMessage(aMsg.toString());
  31. },
  32.  
  33. sessionStore: {
  34. get ss() {
  35. try {
  36. return Components.classes["@mozilla.org/browser/sessionstore;1"].
  37. getService(Components.interfaces.nsISessionStore)
  38. } catch(e) {
  39. return;
  40. }
  41. },
  42.  
  43. getTabValue : function(aTab, aKey) {
  44. if (typeof SessionStore.getCustomTabValue == "function")
  45. return SessionStore.getCustomTabValue(aTab, aKey);
  46. else
  47. return this.ss.getTabValue(aTab, aKey);
  48. },
  49.  
  50. setTabValue : function(aTab, aKey, aValue) {
  51. if (typeof SessionStore.setCustomTabValue == "function")
  52. return SessionStore.setCustomTabValue(aTab, aKey, aValue);
  53. else
  54. return this.ss.setTabValue(aTab, aKey, aValue);
  55.  
  56. },
  57. deleteTabValue : function(aTab, aKey) {
  58. if (typeof SessionStore.deleteCustomTabValue == "function")
  59. return SessionStore.deleteCustomTabValue(aTab, aKey);
  60. else
  61. return this.ss.deleteTabValue(aTab, aKey);
  62. }
  63. },
  64.  
  65. get tabContext() {
  66. return document.getElementById("tabContextMenu");
  67. },
  68.  
  69. init: function(){
  70. console.log("init");
  71. this.tabContextMenu();
  72.  
  73. //tabbrowser.xmlを置き換え
  74. gBrowser.removeTab_org = gBrowser.removeTab;
  75. gBrowser.removeTab = function(aTab, aParams) {
  76. if (aTab.localName != "tab")
  77. aTab = this.selectedTab;
  78. if (aTab.hasAttribute("tabProtect"))
  79. return;
  80. gBrowser.removeTab_org(aTab, aParams);
  81. }
  82.  
  83. gBrowser.isProtectTab = function (aTab){
  84. return aTab.hasAttribute("tabProtect");
  85. }
  86.  
  87. gBrowser.protectTab = function (aTab, state) {
  88. let isProtected;
  89. if (typeof state == "undefined") {
  90. if ( aTab.hasAttribute("tabProtect") ){
  91. state = false;
  92. } else {
  93. state = true;
  94. }
  95. }
  96. if (state) {
  97. aTab.setAttribute("tabProtect", "true");
  98. tabProtect.sessionStore.setTabValue(aTab, "tabProtect", "true");
  99. isProtected = true;
  100. } else {
  101. aTab.removeAttribute("tabProtect");
  102. try {
  103. tabProtect.sessionStore.deleteTabValue(aTab, "tabProtect");
  104. } catch(e) {}
  105. isProtected = false;
  106. }
  107. this.protectTabIcon(aTab);
  108. return isProtected;
  109. }
  110.  
  111. gBrowser.protectTabIcon = function (aTab){
  112. const kXULNS =
  113. "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  114. var image = document.getAnonymousElementByAttribute(
  115. aTab, "class", "tab-icon-protect");
  116. if ( aTab.hasAttribute("tabProtect") ) {
  117. if(!image){
  118. var stack = aTab.querySelector(".tab-stack");
  119. var image = document.createElementNS(kXULNS,'image');
  120. image.setAttribute('class','tab-icon-protect');
  121. image.setAttribute('left',0);
  122. image.setAttribute('top',0);
  123. if(stack) stack.appendChild(image);
  124. }
  125. }
  126. }
  127.  
  128. // CSSを適用
  129. var style = `
  130. tab[tabProtect] .tab-close-button {
  131. display: none;
  132. }
  133. tab[tabProtect] .tab-icon-protect{
  134. margin-top: 0px; /*要調整*/
  135. margin-left: 0px; /*要調整*/
  136. list-style-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAQUlEQVQ4jWNgGAXDADASUvDvOsN/fPJMlLqAhRhFTJqo/H/XKXQBsoFEuQDDVnIMQPcGXJxYA3C5hiwvUOwCZAAAlRcK7m+YgB4AAAAASUVORK5CYII=');
  137. }
  138. tab:not([tabProtect]) .tab-icon-protect {
  139. display: none;
  140. }
  141. `;
  142. var sspi = document.createProcessingInstruction(
  143. 'xml-stylesheet',
  144. 'type="text/css" href="data:text/css,' + encodeURIComponent(style) + '"'
  145. );
  146. document.insertBefore(sspi, document.documentElement);
  147. sspi.getAttribute = function(name) {
  148. return document.documentElement.getAttribute(name);
  149. };
  150.  
  151. this.restoreAll(0);
  152. gBrowser.tabContainer.addEventListener('TabMove', this, false);
  153. gBrowser.tabContainer.addEventListener('SSTabRestoring', this, false);
  154. window.addEventListener('unload', this, false)
  155.  
  156. // detach tab
  157. let func = gBrowser.swapBrowsersAndCloseOther.toString();
  158. if (gBrowser && !/copytabProtect/.test(func)) {
  159. func = func.replace(
  160. 'let otherFindBar = aOtherTab._findBar;',
  161. `if (aOtherTab.hasAttribute("tabProtect")) {
  162. aOurTab.ownerGlobal.gBrowser.protectTab(aOurTab, true);
  163. /*copytabProtect*/
  164. }
  165. $&`
  166. );
  167. eval("gBrowser.swapBrowsersAndCloseOther = function " + func.replace(/^function/, ''));
  168. }
  169. },
  170.  
  171. restoreAll: function(delay = 0) {
  172. var that = this;
  173. setTimeout(init, delay, 0);
  174. function init(i){
  175. if(i < gBrowser.tabs.length){
  176. var aTab = gBrowser.tabs[i];
  177. that.restoreForTab(aTab);
  178. i++;
  179. arguments.callee(i);
  180. }else{
  181. }
  182. }
  183. },
  184.  
  185. uninit: function(){
  186. window.removeEventListener('unload', this, false)
  187. gBrowser.tabContainer.removeEventListener('SSTabRestoring', this, false);
  188. gBrowser.tabContainer.removeEventListener('TabMove', this, false);
  189. this.tabContext.removeEventListener('popupshowing', this, false);
  190.  
  191. },
  192.  
  193. handleEvent: function(event) {
  194. switch(event.type) {
  195. case "unload":
  196. this.uninit(event);
  197. break;
  198. case "SSTabRestoring":
  199. this.restore(event);
  200. break;
  201. case "TabMove":
  202. this.TabMove(event);
  203. break;
  204. case "popupshowing":
  205. this.popupshowing(event);
  206. break;
  207. }
  208. },
  209.  
  210. TabMove: function(aEvent){
  211. var aTab = aEvent.target;
  212. gBrowser.protectTabIcon(aTab);
  213. },
  214.  
  215. tabContextMenu: function(){
  216. //tab context menu
  217. var tabContext = this.tabContext;
  218. var menuitem = this.tabProtectMenu
  219. = tabContext.appendChild(
  220. document.createXULElement("menuitem"));
  221. menuitem.id = "tabProtect";
  222. menuitem.setAttribute("type", "checkbox");
  223. if (Services.appinfo.version.split(".")[0] >= 63)
  224. menuitem.setAttribute("label", "Protect This Tab(s)");
  225. else
  226. menuitem.setAttribute("label", "Protect This Tab");
  227. menuitem.setAttribute("accesskey", "P");
  228. menuitem.setAttribute("oncommand","tabProtect.toggle(TabContextMenu.contextTab);");
  229. tabContext.addEventListener('popupshowing', this, false);
  230. },
  231.  
  232. popupshowing: function(event) {
  233. this.setCheckbox(event);
  234. },
  235.  
  236. restore: function(event){
  237. tabProtect.restoreAll(0);
  238. },
  239.  
  240. restoreForTab: function(aTab){
  241. var retrievedData = this.sessionStore.getTabValue(aTab, "tabProtect") == "true";
  242. console.log("restoreForTab" + retrievedData);
  243. if(retrievedData){
  244. aTab.setAttribute('tabProtect',true);
  245. }
  246. gBrowser.protectTabIcon(aTab);
  247. },
  248.  
  249. toggle: function(aTab){
  250. if (typeof gBrowser.selectedTabs != "undefined") {
  251. this.toggleProtectSelectedTabs(this.getSelectedTabs(aTab));
  252. } else {
  253. gBrowser.protectTab(aTab);
  254. }
  255. },
  256.  
  257. toggleProtectSelectedTabs: function(tabs){
  258. if (tabs.length < 1)
  259. return;
  260. let isProtect = gBrowser.isProtectTab(tabs[0]);
  261. for (let tab of tabs) {
  262. gBrowser.protectTab(tab, !isProtect);
  263. }
  264. },
  265.  
  266. getSelectedTabs: function(aTab){
  267. let contextTab = aTab;
  268. let selectedTabs = [contextTab];
  269. if (gBrowser.selectedTabs.indexOf(contextTab) < 0)
  270. return selectedTabs;
  271.  
  272. for (let tab of gBrowser.selectedTabs) {
  273. if (contextTab != tab)
  274. selectedTabs.push(tab);
  275. }
  276. return selectedTabs;
  277. },
  278.  
  279. setCheckbox: function(event){
  280. var menuitem = this.tabProtectMenu;
  281. var aTab = TabContextMenu.contextTab;
  282. if( !aTab || aTab.localName !='tab'){
  283. menuitem.setAttribute('hidden',true);
  284. return;
  285. }
  286. menuitem.setAttribute('hidden',false);
  287. if(aTab.hasAttribute('tabProtect') && aTab.getAttribute('tabProtect')){
  288. menuitem.setAttribute('checked', true);
  289. }else{
  290. menuitem.setAttribute('checked', false);
  291. }
  292. }
  293. }
  294.  
  295. // We should only start the redirection if the browser window has finished
  296. // starting up. Otherwise, we should wait until the startup is done.
  297. if (gBrowserInit.delayedStartupFinished) {
  298. tabProtect.init();
  299. } else {
  300. let delayedStartupFinished = (subject, topic) => {
  301. if (topic == "browser-delayed-startup-finished" &&
  302. subject == window) {
  303. Services.obs.removeObserver(delayedStartupFinished, topic);
  304. tabProtect.init();
  305. }
  306. };
  307. Services.obs.addObserver(delayedStartupFinished,
  308. "browser-delayed-startup-finished");
  309. }
Add Comment
Please, Sign In to add comment