Skip to content

Instantly share code, notes, and snippets.

@satyr
Created February 20, 2009 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save satyr/67522 to your computer and use it in GitHub Desktop.
Save satyr/67522 to your computer and use it in GitHub Desktop.
Reopens tabs you've closed recently.
const Name = 'undo-closed-tabs',
SS = Cc['@mozilla.org/browser/sessionstore;1'].getService(Ci.nsISessionStore),
Style = <style>{<><![CDATA[
@, @* {margin:0; padding:0}
@button {border-width:1px;
font:bold 112% "Consolas",monospace; vertical-align:top}
@li {list-style-type:none}
@img {width:16px; height:16px}
@span.url {display:inline-block; white-space:pre; font-size:88%}
@img, @span {vertical-align:middle}
]]></>.toString().replace(/@/g, '.'+ Name +' ')}</style>;
CmdUtils.CreateCommand({
name: Name,
synonyms: ['uct'],
icon: 'chrome://ubiquity/skin/icons/arrow_undo.png',
description: "Reopens tabs you've closed recently.",
help: (''+<ul style="list-style-image:none">
<li>Use accesskey or click to undo.</li>
<li>Type <abbr title="Regular Expression">regex</abbr>
to filter by title and/or url.</li></ul>),
takes: {regex: {_name: '/re/i', suggest: function(txt, htm, cb, sx){
if(sx) return [];
try { var re = RegExp(txt, 'i') } catch(_){ re = /^/ }
return [{text: txt, data: re, summary: re}];
}}},
execute: function({data}){
for each(var {id} in this._find(data)) this._undo(id);
},
preview: function(pbl, {data}){
if(!SS.getClosedTabCount(context.chromeWindow))
return this._puts(pbl, 'No closed tabs found.');
var ol = this._find(data).reduce(function(ol, {id, title, image, url}, i){
var k = String.fromCharCode(i + 65);
ol.li += (<li><label for={id}><span class="title"><button id={id}
accesskey={k}>{k}</button><img src={image}
/>{title}</span><span class="url">{url}</span></label></li>);
return ol;
}, <ol class={Name}></ol>);
if(!('li' in ol)) return this._puts(pbl, 'No tabs matched.');
(jQuery(pbl).html(Style + ol +'')
.find('button').each(function(me){
this.addEventListener('focus', function(e){
var li = this.parentNode.parentNode.parentNode;
li.parentNode.removeChild(li);
me._undo(+this.id);
e.preventDefault(), e.stopPropagation();
}, true);
}, [this]));
},
previewDelay: 333,
_puts: function(pbl, msg){
pbl.innerHTML = <i>{msg}</i>.toXMLString() + this.help;
},
_find: function(re){
var ls = this._list = eval(SS.getClosedTabData(context.chromeWindow));
ls.forEach(function(t, i){ t.id = i; [{url: t.url}] = t.state.entries });
return re ? ls.filter(function(t) re.test(t.title) || re.test(t.url)) : ls;
},
_undo: function(id){
this._list.every(function(t, i, l){
if(id !== t.id) return 1;
SS.undoCloseTab(context.chromeWindow, i);
l.splice(i, 1);
});
},
author: ['powchin'.link('http://friendfeed.com/powchin'),
'satyr'.link('http://d.hatena.ne.jp/murky-satyr')].join(', '),
license: 'MIT',
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment