Lock and Protect App Tab – 锁定和保护App Tab - 20110330更新

(12,735 views)
September 28, 2010

20110330更新 – 添加一个tabFreezeLite脚本
20110318更新 – 升级lockAndProtectAppTab.uc脚本
20110317更新 – 添加tabLockLite和tabProtectLite脚本
20101207更新 – 添加3合一脚本

firefox在4.0版中引入了App Tab的概念。

可以通过pin tab操作把一个标签页标记成app tab,这样这个标签页就会排列在标签栏的前部,并只显示icon。

一般我们都是把web app标记成app tab,比如greader, gmail, web im等,通常希望这些应用能够常驻,并且不会由于误操作而被关闭或者跳转到其他页面去。

这时候就需要把App Tab给保护(protect)和锁定(lock)起来。

Protect Tab – 保护标签页

  • If you want to make sure that a tab cannot be closed. This is useful to make certain you don’t accidentally close a tab.
  • 被protect的标签页不能被关闭。比如通过点击标签页右键后的Close Tab选项,ctrl+w等快捷键,以及其他脚本提供的关闭功能(如双击标签页)

Lock Tab – 锁定标签页

  • A lock tab cannot navigate to a new URL. This means that it is “locked” on the current URL. If you have this tab selected and you click a bookmark link, history, or a link on the page, the link will open in a new tab.
  • 被lock的标签页不能跳转到别的地址,lock的意思就是这个标签页被锁定在了当前的地址上。

通过alice0775的tabProtect和tabLock脚本,可以在标签页的右键菜单中添加Protect This Tab和Lock This Tab两个功能选项

附件:
tabProtect_mod1.uc
tabLock_mod1.uc
作者一直在维护这两个脚本,可以在这个页面查找更新

最后利用下面这个脚本,可以使标签页在被标记成App Tab时,自动lock并protect起来。
20110318升级v0.02

  • 保证pinTab后标签处于locked和protected状态,unpinTab后处于未locked和protected状态。
    原来存在“已locked的标签被pinTab操作后,状态是未locked但protected”的问题。
  • 修复重启时AppTab状态出错的问题

附件:lockAndProtectAppTab_v0.02.uc

附件:3合一脚本tabProtect&Lock&MergeWithAppTab.uc

附录,lock和protect tab的代码,可用于鼠标手势和快捷键

gBrowser.lockTab(gBrowser.selectedTab);
gBrowser.protectTab(gBrowser.selectedTab);

————————————————————————————————-
20110330更新
应网友tyc600要求,在标签右键菜单中添加Freeze this tab选项(冷冻):同时Protect和Lock当前标签(或者解除)
tabFreezeLite.uc

20110317更新
基于alice0775的脚本,针对firefox4精简重构了下,删除了很多用不到的兼容代码,修复了在4.0下的一些错误,并进行了一定程度上增强,封装成tabLockLite和tabProtectLite

  • tabProtectLite.uc
    用下面的CSS可以样式化被保护的标签

    .tabProtect {
        background-image: none !important;
        background-color:#ffffcc !important; /* 被保护的标签的背景色 */
    }
    
    /* 给被保护的标签添加一个P(rotect)图标 */
    .tab-icon-protect{
        width: 8px !important;
        height: 8px !important;
        margin-right: 2px !important;
        background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAEpJREFUOE9jZGD4/58BJ2DELYWQ+f//379/KBhiKNhgojBcM0wjyMCBMQDmFYq9QH8DEDbCQp/EWKDQAOLiGk+aGDWA2AxDs0AEAGLjTI40TktLAAAAAElFTkSuQmCC') !important;
    }
    
    /* 被保护的App Tab不显示P图标 */
    tab[pinned="true"] .tab-icon-protect {
        display: none !important;
    }
    
    /* 隐藏时不显示 */
    .tab-icon-protect[hidden='true'] {
        display: none !important;
    }
    

  • tabLockLite.uc

    1. 配置参数
      ignoreHashLink – lock后是否允许当前页面内锚点间跳转,bool类型
      true的话,允许;false的话,点击不会跳转到当前页面的锚点,而是新开tab打开。一般设置为true。

      ignoreBrowserBackForward – lock后是否允许forward/back,整数类型

      0:允许
      1:新开tab打开forward/back的页面
      2:不允许

      这两个参数可以在脚本里配置,另外还有对应的preference配置项,可以在about:config里手动添加。

      userChrome.tabLock.ignoreBrowserBack_Forward
      userChrome.tabLock.ignoreHashLink

      about:config里的配置项优先级高。
      建议在about:config添加preference配置项配置,可以即时修改生效,不必重启。

    2. 相关的还有firefox内置的几个跟Tab有关的preference配置项,酌情设置
      browser.tabs.loadInBackground
      browser.tabs.loadBookmarksInBackground
    3. CSS
      跟tabProtect类似,可以用下面的CSS代码样式化被lock的标签

      .tabLock {
          background-image: none !important;
          background-color: pink !important; /* 被lock的标签的背景色 */
      }
      
      /* 给被lock的标签添加一个L(ock)图标 */
      .tab-icon-lock{
          width: 8px !important;
          height: 8px !important;
          margin-right: 2px !important;
          background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAjElEQVQ4je3RsQ7CMAyE4S9pURl5/6csGxKJw1AKFBARK+IkD3Fyv86OQouHOhNBqzQcdJSPzCKIEMgkKFTMXcDmMI6LGzuGnvkFoBRQiWtn/x1g5dwBpx4gnalDxAZUcm4jad3HxwTpzaNxmtZef4RMkrNbDQPTtN53AanSniM0S6y8/ES82v76MV0AlREpDobXTpUAAAAASUVORK5CYII=') !important;
      }
      
      /* L图标在被lock的App Tab上不显示 */
      tab[pinned="true"] .tab-icon-lock {
          display: none !important;
      }
      
      .tabbrowser-tab[fadein] .tab-stack,
      .tabbrowser-tab[fadein]:hover .tab-stack,
      .tabbrowser-tab[fadein][selected="true"] .tab-stack,
      .tabbrowser-tab[fadein][selected="true"]:hover .tab-stack  {
          border-top: transparent solid 1px;
      }
      
      .tabbrowser-tab[tabLock="true"][fadein] .tab-stack,
      .tabbrowser-tab[tabLock="true"][fadein]:hover .tab-stack,
      .tabbrowser-tab[tabLock="true"][fadein][selected="true"]:hover .tab-stack  {
          border-top: red solid 1px;
      }
      /* 给被lock的标签添加一道红线 */
      

    4. CSS部分请按需修改:
      比如颜色修改成自己感觉舒服的,图标也可以换成其他更形象的东西,比如小锁、小怪物什么的。。。
      其实如果CSS比较熟的话,最好能把图标缩小后挪到site icon的角上,看起来更像是被lock或者protect了。


related post

(12,735 views)

16 Responses to Lock and Protect App Tab – 锁定和保护App Tab

  1. wql says:

    怎么写脚本用Firegesture调用锁定、保护标签页

  2. harnack says:

    这个alice真是个高人,写了无数的脚本(和扩展)。话说起这么个名字,难道是个女程序员么?

  3. jeo says:

    3.6有个把两个和一起的脚本,这三个脚本和成一个多好

    • admin says:

      合并起来很容易,参见更新。

      但是个人建议还是分开比较好,有利于更新。

  4. tyc600 says:

    能不能麻烦一下您,

    将锁定和保护合并为一个命令,同时实现两个功能,

    有时间的话,能不能麻烦您一下

    • admin says:

      不知道你用不用keyconfig或者firegesture,建个新的快捷键,填上如下代码
      gBrowser.lockTab(gBrowser.selectedTab);
      gBrowser.protectTab(gBrowser.selectedTab);
      就可以同时锁定和保护当前标签

      • tyc600 says:

        是鼠标手势么?

        鼠标手势我基本只用于页面上,下,后退,前进,其他的误操作太多就没用

  5. tyc600 says:

    我找到了冻结标签的代码,不过这个代码会出现三个菜单项—保护,锁定,冻结,
    冻结就是同时启动保护和锁定,但是
    1) 如何隐藏这两个,只显示冻结,
    2) 用这个代码实现的冻结,没有标签CSS变化,就很难用眼分辨那个锁定,那个没锁.

    请求帮助

    //保护标签页、锁定标签页、冻结标签页
    (function() {
    if (“TM_init” in window || “tabberwocky” in window) return;

    var tabContextMenu = document.getAnonymousElementByAttribute(gBrowser, “anonid”, “tabContextMenu”);
    var protectTabMenuitem = tabContextMenu.insertBefore(document.createElement(“menuitem”), document.getElementById(“context_closeTab”));
    protectTabMenuitem.setAttribute(“id”, “context_protectTab”);
    protectTabMenuitem.setAttribute(“label”, getPref(“general.useragent.locale”).indexOf(“zh”)==-1 ? “Protect Tab” : “\u4FDD\u62A4\u6807\u7B7E\u9875″);
    protectTabMenuitem.setAttribute(“type”, “checkbox”);
    protectTabMenuitem.setAttribute(“accesskey”, “P”);
    protectTabMenuitem.setAttribute(“key”, “key_protectTab”);
    protectTabMenuitem.setAttribute(“oncommand”, “gBrowser.protectTab(gBrowser.mContextTab);”);

    var lockTabMenuitem = tabContextMenu.insertBefore(document.createElement(“menuitem”), document.getElementById(“context_closeTab”));
    lockTabMenuitem.setAttribute(“id”, “context_lockTab”);
    lockTabMenuitem.setAttribute(“label”, getPref(“general.useragent.locale”).indexOf(“zh”)==-1 ? “Lock Tab” : “\u9501\u5B9A\u6807\u7B7E\u9875″);
    lockTabMenuitem.setAttribute(“type”, “checkbox”);
    lockTabMenuitem.setAttribute(“accesskey”, “L”);
    lockTabMenuitem.setAttribute(“key”, “key_lockTab”);
    lockTabMenuitem.setAttribute(“oncommand”, “gBrowser.lockTab(gBrowser.mContextTab);”);

    var freezeTabMenuitem = tabContextMenu.insertBefore(document.createElement(“menuitem”), document.getElementById(“context_closeTab”));
    freezeTabMenuitem.setAttribute(“id”, “context_freezeTab”);
    freezeTabMenuitem.setAttribute(“label”, getPref(“general.useragent.locale”).indexOf(“zh”)==-1 ? “Freeze Tab” : “\u51BB\u7ED3\u6807\u7B7E\u9875″);
    freezeTabMenuitem.setAttribute(“type”, “checkbox”);
    freezeTabMenuitem.setAttribute(“accesskey”, “F”);
    freezeTabMenuitem.setAttribute(“key”, “key_freezeTab”);
    freezeTabMenuitem.setAttribute(“oncommand”, “gBrowser.freezeTab(gBrowser.mContextTab);”);
    // tabContextMenu.insertBefore(document.createElement(“menuseparator”), document.getElementById(“context_closeTab”));

    hookCode(“gBrowser.updatePopupMenu”, “}”, function() {
    document.getElementById(“context_protectTab”).setAttribute(“checked”, this.mContextTab.hasAttribute(“protected”));
    document.getElementById(“context_lockTab”).setAttribute(“checked”, this.mContextTab.hasAttribute(“locked”));
    document.getElementById(“context_freezeTab”).setAttribute(“checked”, this.mContextTab.hasAttribute(“protected”) && this.mContextTab.hasAttribute(“locked”));
    document.getElementById(“context_closeTab”).disabled = this.mContextTab.hasAttribute(“protected”);
    });

    hookCode(“gBrowser.onTabRestoring”, “}”, function() {
    var aTab = event.target;
    var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
    if (ss.getTabValue(aTab, “protected”)) {
    aTab.setAttribute(“protected”, true);
    }
    if (ss.getTabValue(aTab, “locked”)) {
    aTab.setAttribute(“locked”, true);
    }
    });

    var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
    for (var i=0; i<gBrowser.mTabs.length; i++) {
    var aTab = gBrowser.mTabs[i];
    if (ss.getTabValue(aTab, "protected")) {
    aTab.setAttribute("protected", true);
    }
    if (ss.getTabValue(aTab, "locked")) {
    aTab.setAttribute("locked", true);
    }
    }

    gBrowser.protectTab = function(aTab) {
    if (!aTab)
    aTab = this.mCurrentTab;

    var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
    if (aTab.hasAttribute("protected")) {
    aTab.removeAttribute("protected");ss.deleteTabValue(aTab, "protected");
    }
    else {
    aTab.setAttribute("protected", true);ss.setTabValue(aTab, "protected", true);
    }
    }

    gBrowser.lockTab = function(aTab) {
    if (!aTab)
    aTab = this.mCurrentTab;

    var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
    if (aTab.hasAttribute("locked")) {
    aTab.removeAttribute("locked");ss.deleteTabValue(aTab, "locked");
    }
    else {
    aTab.setAttribute("locked", true);ss.setTabValue(aTab, "locked", true);
    }
    }

    gBrowser.freezeTab = function(aTab) {
    if (!aTab)
    aTab = this.mCurrentTab;

    var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
    if (aTab.hasAttribute("protected") && aTab.hasAttribute("locked")) {
    aTab.removeAttribute("protected");ss.deleteTabValue(aTab, "protected");
    aTab.removeAttribute("locked");ss.deleteTabValue(aTab, "locked");
    }
    else {
    aTab.setAttribute("protected", true);ss.setTabValue(aTab, "protected", true);
    aTab.setAttribute("locked", true);ss.setTabValue(aTab, "locked", true);
    }
    }

    hookCode("gBrowser.duplicateTab", /.*ss.duplicateTab.*/, function() {
    var tab = ss.duplicateTab(window, aTab);
    if (tab.hasAttribute("protected")) {
    this.protectTab(tab);
    }
    if (tab.hasAttribute("locked")) {
    this.lockTab(tab);
    }
    return tab;
    });

    hookCode("gBrowser.removeTab", "{", function() {
    if (aTab.hasAttribute("protected")) {
    return;
    }
    });

    hookCode("gBrowser.loadURI", "{", function() {
    if (this.selectedTab.hasAttribute("locked")) {
    return this.loadOneTab(aURI, aReferrerURI, aCharset, null, getPref("browser.tabs.loadInBackground", false), false);
    }
    });

    hookCode("gBrowser.loadURIWithFlags", "{", function() {
    if (this.selectedTab.hasAttribute("locked")) {
    return this.loadOneTab(aURI, aReferrerURI, aCharset, aPostData, getPref("browser.tabs.loadInBackground", false), aFlags & Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP);
    }
    });

    hookCode("contentAreaClick", /(?=.*else.*\n.*handleLinkClick)/, function() {
    if (gBrowser.selectedTab.hasAttribute("locked")) {
    openNewTabWith(wrapper.href, wrapper.ownerDocument, null, event, false);
    event.stopPropagation();
    return false;
    }
    });
    })();

    • admin says:

      原来你是要有个在标签上的右键菜单啊
      参见正文更新 – tabFreezeLite.uc.js
      保护和锁定的菜单项不想显示的,用CSS隐藏掉就行

      #tabProtect, #tabLock {
      display:none !important;
      }

    • admin says:

      你能贴你这个脚本的地址吗
      我想把这个代码删了,在留言里太占地方,而且不能格式化显示

  6. jiayiming says:

    tabProtectLite.uc似乎锁定app重启后标题文字就是“加载中…”了 刷新也没用 原作者网站上的链接似乎也打不开了

①若要贴代码,请将 "<" 改成 "&lt;",">" 改成 "&gt;".
②若要从他人留言中复制代码,注意检查引号可能是中文的,请手动修改成英文符号,避免不能工作