Skip to content

Instantly share code, notes, and snippets.

@rrichards
Forked from satyr/google++.ubiq.js
Created October 18, 2009 09:50
Show Gist options
  • Save rrichards/212616 to your computer and use it in GitHub Desktop.
Save rrichards/212616 to your computer and use it in GitHub Desktop.
const
Google = 'http://www.google.com/',
GImage = 'http://image.google.com/',
GVideo = 'http://video.google.com/',
Gmail = 'https://mail.google.com/mail/',
GReader = Google +'reader/',
GCode = Google + 'codesearch',
GLogos = Google +'logos/',
GSgFAQ = 'suggest'.link('http://labs.google.com/suggestfaq.html'),
PPath = 'extensions.ubiquity.google.',
PLang = PPath +'lang',
PSafe = PPath +'safe',
PSize = PPath +'size',
PFrom = PPath +'from',
PLogo = PPath +'logo',
{prefs} = Application,
CSS = <![CDATA[
body {position:relative; line-height:1.23}
li {margin-bottom:0.2em}
a img {border:none; vertical-align:middle}
kbd {text-decoration:underline; margin:0 4px 0 1px}
button {padding:0; border-width:1px; text-transform:uppercase}
button, kbd {font:bold 92% monospace}
button.active {background-color:transparent; color:inherit}
button.number[disabled] {text-decoration:underline}
.list {list-style:none; padding:0; margin:0}
.favicon {margin-right:0.1em}
.count {position:absolute; right:4px}
.pagination {text-align:center}
.marker {margin-right:3px; vertical-align:bottom}
.bracket {font-size:88%}
.domain {font:92% monospace}
.content {font-size:96%}
.error {font-style:oblique; line-height:1.8}
.logo {display:inline-block; clear:both}
.logo[value]:hover::after {
content:attr(value); display:inline-block;
position:absolute; bottom:0; right:1ex; z-index:2;
font:bolder smaller sans-serif}
.loading {opacity:0.9}
.loading + .logo {opacity:0.4}
.error + .logo {opacity:0.7}
]]>,
Langs = (noun_type_lang_google._list
.reduce(function(o, s)(o[s.text] = s.data, o), {'*': ''})),
Regions = {
'*': '',
Afghanistan: 'AF', Albania: 'AL', Algeria: 'DZ', 'American Samoa': 'AS',
Andorra: 'AD', Angola: 'AO', Anguilla: 'AI', Antarctica: 'AQ',
'Antigua and Barbuda': 'AG', Argentina: 'AR', Armenia: 'AM', Aruba: 'AW',
Australia: 'AU', Austria: 'AT', Azerbaijan: 'AZ', Bahamas: 'BS',
Bahrain: 'BH', Bangladesh: 'BD', Barbados: 'BB', Belarus: 'BY',
Belgium: 'BE', Belize: 'BZ', Benin: 'BJ', Bermuda: 'BM',
Bhutan: 'BT', Bolivia: 'BO', 'Bosnia and Herzegovina': 'BA',
Botswana: 'BW', 'Bouvet Island': 'BV', Brazil: 'BR',
'British Indian Ocean Territory': 'IO', 'British Virgin Islands': 'VG',
Brunei: 'BN', Bulgaria: 'BG', 'Burkina Faso': 'BF', Burundi: 'BI',
Cambodia: 'KH', Cameroon: 'CM', Canada: 'CA', 'Cape Verde': 'CV',
'Cayman Islands': 'KY', 'Central African Republic': 'CF', Chad: 'TD',
Chile: 'CL', China: 'CN', 'Christmas Island': 'CX',
'Cocos Islands': 'CC', Colombia: 'CO', Comoros: 'KM',
'Congo - Brazzaville': 'CG', 'Congo - Kinshasa': 'CD',
'Cook Islands': 'CK', 'Costa Rica': 'CR', Croatia: 'HR',
Cuba: 'CU', Cyprus: 'CY', 'Czech Republic': 'CZ',
Denmark: 'DK', Djibouti: 'DJ', Dominica: 'DM',
'Dominican Republic': 'DO', Ecuador: 'EC', Egypt: 'EG',
'El Salvador': 'SV', 'Equatorial Guinea': 'GQ', Eritrea: 'ER',
Estonia: 'EE', Ethiopia: 'ET', 'Falkland Islands': 'FK',
'Faroe Islands': 'FO', Fiji: 'FJ', Finland: 'FI',
France: 'FR', 'French Guiana': 'GF', 'French Polynesia': 'PF',
'French Southern Territories': 'TF', Gabon: 'GA', Gambia: 'GM',
Georgia: 'GE', Germany: 'DE', Ghana: 'GH', Gibraltar: 'GI', Greece: 'GR',
Greenland: 'GL', Grenada: 'GD', Guadeloupe: 'GP', Guam: 'GU',
Guatemala: 'GT', Guinea: 'GN', 'Guinea-Bissau': 'GW',
Guyana: 'GY', Haiti: 'HT', 'Heard Island and McDonald Islands': 'HM',
Honduras: 'HN', 'Hong Kong SAR China': 'HK', Hungary: 'HU',
Iceland: 'IS', India: 'IN', Indonesia: 'ID', Iran: 'IR', Iraq: 'IQ',
Ireland: 'IE', Israel: 'IL', Italy: 'IT', 'Ivory Coast': 'CI',
Jamaica: 'JM', Japan: 'JP', Jordan: 'JO', Kazakhstan: 'KZ', Kenya: 'KE',
Kiribati: 'KI', Kuwait: 'KW', Kyrgyzstan: 'KG', Laos: 'LA',
Latvia: 'LV', Lebanon: 'LB', Lesotho: 'LS', Liberia: 'LR', Libya: 'LY',
Liechtenstein: 'LI', Lithuania: 'LT', Luxembourg: 'LU',
'Macau SAR China': 'MO', Macedonia: 'MK', Madagascar: 'MG', Malawi: 'MW',
Malaysia: 'MY', Maldives: 'MV', Mali: 'ML', Malta: 'MT',
'Marshall Islands': 'MH', Martinique: 'MQ', Mauritania: 'MR',
Mauritius: 'MU', Mayotte: 'YT', Mexico: 'MX', Micronesia: 'FM',
Moldova: 'MD', Monaco: 'MC', Mongolia: 'MN', Montserrat: 'MS',
Morocco: 'MA', Mozambique: 'MZ', Myanmar: 'MM', Namibia: 'NA', Nauru: 'NR',
Nepal: 'NP', Netherlands: 'NL', 'Netherlands Antilles': 'AN',
'New Caledonia': 'NC', 'New Zealand': 'NZ', Nicaragua: 'NI', Niger: 'NE',
Nigeria: 'NG', Niue: 'NU', 'Norfolk Island': 'NF',
'North Korea': 'KP', 'Northern Mariana Islands': 'MP', Norway: 'NO',
Oman: 'OM', Pakistan: 'PK', Palau: 'PW',
'Palestinian Territory': 'PS', Panama: 'PA', 'Papua New Guinea': 'PG',
Paraguay: 'PY', Peru: 'PE', Philippines: 'PH', Pitcairn: 'PN',
Poland: 'PL', Portugal: 'PT', 'Puerto Rico': 'PR', Qatar: 'QA',
Reunion: 'RE', Romania: 'RO', Russia: 'RU', Rwanda: 'RW',
'Saint Helena': 'SH', 'Saint Kitts and Nevis': 'KN', 'Saint Lucia': 'LC',
'Saint Pierre and Miquelon': 'PM', 'Saint Vincent and the Grenadines': 'VC',
Samoa: 'WS', 'San Marino': 'SM', 'Sao Tome and Principe': 'ST',
'Saudi Arabia': 'SA', Senegal: 'SN', Serbia: 'YU', Seychelles: 'SC',
'Sierra Leone': 'SL', Singapore: 'SG', Slovakia: 'SK',
Slovenia: 'SI', 'Solomon Islands': 'SB', Somalia: 'SO',
'South Africa': 'ZA', 'South Georgia and the South Sandwich Islands': 'GS',
'South Korea': 'KR', Spain: 'ES', 'Sri Lanka': 'LK', Sudan: 'SD',
Suriname: 'SR', 'Svalbard and Jan Mayen': 'SJ', Swaziland: 'SZ',
Sweden: 'SE', Switzerland: 'CH', Syria: 'SY', Taiwan: 'TW',
Tajikistan: 'TJ', Tanzania: 'TZ', Thailand: 'TH', Togo: 'TG', Tokelau: 'TK',
Tonga: 'TO', 'Trinidad and Tobago': 'TT', Tunisia: 'TN',
Turkey: 'TR', Turkmenistan: 'TM', 'Turks and Caicos Islands': 'TC',
Tuvalu: 'TV', 'U.S. Virgin Islands': 'VI', Uganda: 'UG',
Ukraine: 'UA', 'United Arab Emirates': 'AE', 'United Kingdom': 'GB',
'United States': 'US', 'United States Minor Outlying Islands': 'UM',
Uruguay: 'UY', Uzbekistan: 'UZ', Vanuatu: 'VU', Vatican: 'VA',
Venezuela: 'VE', Vietnam: 'VN', 'Wallis and Futuna': 'WF',
'Western Sahara': 'EH', Yemen: 'YE', Zambia: 'ZM', Zimbabwe: 'ZW',
},
GIOpts = {
size_imgsz : 'icon small medium large xlarge xxlarge huge',
type_imgtype: 'news face clipart lineart photo',
tone_imgc : 'mono color',
color_imgcolor: ('red orange yellow green teal blue purple pink '+
'white gray black brown'),
safe_safe : 'active moderate off',
},
NounGIOpts = (function(){
var v2k = {};
for(let name_key in GIOpts){
let key = name_key.split('_')[1];
for each(let val in GIOpts[name_key].split(' ')) v2k[val] = key;
}
return {
name: "gimage options",
label: "options",
suggest: function gio_suggest(txt, htm, cb, sx){
if(sx || !txt) return [];
var vals = txt.split(/[\s,]+/), lastv = vals.pop();
var dic = {__proto__: null};
for(let i in vals){
let v = vals[i];
vals[i] = '-';
for(let val in v2k) if(val.indexOf(v) === 0){
let key = v2k[val];
if(key in dic) continue;
vals[i] = val;
dic[key] = 1;
break;
}
}
var ss = [];
for(let val in v2k) if(val.indexOf(lastv) === 0){
let vs = vals.concat(val), data = {}
for each(let v in vs) data[v2k[v]] = v;
ss.push(CmdUtils.makeSugg(vs.join(','), null, data));
}
return ss;
},
};
}());
function googleCommand(o){
o.icon || (o.icon = 'chrome://ubiquity/skin/icons/google.ico');
o.author = {name: 'satyr', email: '[email protected]'};
o.license = 'MIT';
CmdUtils.CreateCommand(o);
}
function tie(it, fn){
(it[0] || it).addEventListener('focus', function({target: b}){
if(/^(?!button$)/i.test(b.nodeName)) return;
b.blur();
b.disabled = true;
b.className += ' active';
fn.call(b, b);
}, true);
}
function ng(c){
c.textContent = Array.slice(arguments, 1).join(' ');
c.className = 'error';
}
function ngx(c) function g_errorjax(x, s){
ng(c, x.status, x.statusText, ' (', s, ')');
};
function paginates(cpi, l)(
btn('&lt;,', ',', cpi <= 1, cpi - 1) +
[btn(++i, i, cpi === i, i) for(i in Array(l)+0)].join('') +
btn('.&gt;', '.', cpi >= l, cpi + 1));
function btn(txt, key, dis, val)(
'<button accesskey="'+ key +'" value="'+ val + '" class="'+ typeof key +
(dis ? '" disabled="disabled">' : '">') + txt +'</button>');
function keys(i)({a2h: 'ABCDEFGH'[i], i2p: 'IJKLMNOP'[i], q2x: 'QRSTUVWX'[i]});
function params(args, xq){
var q = args.object.text.trim();
if(!q) return "";
if(xq) q = xq(q);
var site = (args.source || 0).text;
if(site) q += " site:" + site;
var ps = {
q: q, ie: 'utf-8', v: '1.0',
hl: args.format.data || prefs.getValue(PLang, ''),
gl: prefs.getValue(PFrom, ''),
safe: prefs.getValue(PSafe, ''),
};
var {data} = args.modifier || 0;
for(let k in data) ps[k] = data[k];
return ps;
}
function listenOnce(target, type, fn, ucap){
target.addEventListener(type, function onevent(ev){
target.removeEventListener(type, onevent, ucap);
fn.call(this, ev);
}, ucap);
}
function fdurat(s) (s / 60 | 0) +':'+ (s % 60 + 100 + '').slice(-2);
function xml(x){
XML.ignoreWhitespace = true;
try {
return XML(x.replace(/^\s*<\?[^>]*>/, '').replace(/ xmlns=".+?"/g, ''));
} catch(e if e instanceof SyntaxError){
Utils.reportInfo(x);
return null;
}
}
function rawxml(x){
XML.prettyPrinting = XML.ignoreWhitespace = false;
return x && x.toXMLString();
}
function loget(){
var d = new Date;
if (d - loget.last < 30 * 6e4) return;
loget.last = d;
$.ajax({url: Google +'logos/logos.xml', dataType: 'xml', success: logot});
}
function logot(xml){
var i = 1 + (Math.random() * 7 | 0);
var $dsc = $(xml.getElementsByTagName('description')[i].textContent);
var img = $dsc.find('img')[0];
var date = $dsc.find('strong')[0].nextSibling.nodeValue;
gLogo.@src = img.src;
gLogo.@height = img.naturalHeight || '';
gLogo.parent().@value =
xml.getElementsByTagName('title')[i].textContent +'\u3000'+ date;
}
var gLogo = <img src={Google +'intl/en_ALL/images/logo.gif'} height="80"/>;
loget();
rawxml();
(function gsearchCommand({
names, desc, help, top, api, path, ds, drsz,
xargs, list, css, logo, xq}){
const [Name] = names,
Style = '<style>'+ CSS + css +'</style>',
Base = (<div class={Name}><div id={Name}> </div></div>);
Base.appendChild(
<a class="logo" accesskey="^" href={top}/>.appendChild(logo));
var args = {
object: {
name: 'google-suggest'+ (ds ? '-'+ ds : ''),
label: '?',
suggest: function g_suggest(txt, htm, cb, sx){
if(!txt) return [];
var ss = [CmdUtils.makeSugg(txt, htm, null, .4, sx)];
sx || ss.push($.getJSON(
'http://suggestqueries.google.com/complete/search',
{hjson: 't', hl: prefs.getValue(PLang, ''), ds: ds, q: txt},
function g_suget([, ss]){
ss.length &&
cb([{text: q, summary: q +' '+ n.small(), score: .3}
for each([q, n] in ss)]);
}));
return ss;
},
},
format: noun_type_lang_google,
source: {
name: "google site search",
label: "site",
suggest: function gss_suggest(txt, htm, cb, sx){
if(sx || !(txt = txt.trim())) return;
var ss = [txt], site =
CmdUtils.getDocument().location.href.replace(/^\w+[:/]+/, '');
while((site = site.replace(/\/?[^/]*$/, '')))
site === txt || ss.push(site);
return [CmdUtils.makeSugg(s) for each(s in ss)];
},
}
};
for(let role in xargs) args[role] = xargs[role];
var opts = {
names: names,
description: desc,
help: help,
arguments: args,
execute: function g_execute(args){
var ps = params(args, xq);
if(ps.gl) ps.cr = 'country'+ ps.gl;
delete ps.gl;
if(ps && Name === 'google'){
ps.as_qdr = 'y19';
if(context.chromeWindow.gUbiquity.lastKeyEvent.ctrlKey){
ps.source = 'hp';
ps.btnI = '';;
}
}
Utils.openUrlInBrowser(top + (ps && path + Utils.paramsToString(ps)));
},
preview: function g_preview(pb, args, index){
var cn, ps = params(args, xq);
while(!(cn = pb.ownerDocument.getElementById(Name)))
pb.innerHTML = Style + rawxml(Base);
if(!ps) return;
ps.start = index << ((ps.rsz = prefs.getValue(PSize, '') || drsz)
=== 'small' ? 2 : 3);
cn.className += ' loading';
CmdUtils.previewAjax(pb, {
url: api, data: ps, dataType: 'json',
success: function g_success(r){
var {results, cursor} = r.responseData || 0;
if(!results)
return ng(cn, r.responseStatus, ':', r.responseDetails);
if(!results.length)
return ng(cn, 'No results.');
with(cursor) cn.innerHTML = (
'<div class="count"><a title="more" href="'+
moreResultsUrl +'" accesskey="z">'+
(estimatedResultCount +'').match(/.+?(?=(?:...)*$)/g).join(',') +
'</a><kbd>Z</kdb></div><div class="pagination">'+
paginates(currentPageIndex + 1, pages.length) +
'</div><ul class="list">'+ results.map(list).join('') +'</ul>');
tie(cn.getElementsByClassName('list'), function g_open(){
var r = results[this.id];
Utils.openUrlInBrowser(r.unescapedUrl || r.url);
});
tie(cn.getElementsByClassName('pagination'),
function g_page(){ g_preview(pb, args, this.value - 1) });
prefs.getValue(PLogo, true) ||
(pb.getElementsByClassName('logo')[0].style.display = 'none');
cn.className = '';
loget();
},
error: ngx(cn),
});
},
};
if(typeof help !== 'function') opts.help = help;
else opts.__defineGetter__('help', help);
googleCommand(opts);
return arguments.callee;
})({
names: ['google', '/'],
desc: 'Google'.link(Google) +' + multi-page + '+ GSgFAQ,
help: function g_help()(
'Hold <kbd>ctrl</kbd> to feel lucky.' +
[[<a href={Google +'language_tools'}>Language</a>,
PLang, Langs, ''],
[<a href={Google +'safesearch_help.html'}>Safe Search</a>,
PSafe, {active: 'active', moderate: 'moderate', off: 'off'}, 'moderate'],
[<>Result Size</>, PSize, {default: '', 4: 'small', 8: 'large'}, ''],
[<>Region</>,
PFrom, Regions, ''],
[<a href={GLogos}>Logo</a>,
PLogo, {on: true, off: false}, true],
].reduce(function(ul, [name, pref, dict, defv]){
defv = prefs.getValue(pref, defv);
var select = <select onchange={
'Application.prefs.setValue("'+ pref +'", eval(this.value))'}/>;
for(var [key, val] in new Iterator(dict)){
var opt = <option value={uneval(val)}>{key}</option>;
if(val === defv) opt.@selected = 'selected';
select.appendChild(opt);
}
return ul.appendChild(<li>{name} </li>.appendChild(select));
}, <ul style="list-style:none"/>)),
top: Google,
api: 'http://ajax.googleapis.com/ajax/services/search/web',
path: 'search',
ds: '',
drsz: 'small',
list: function g_list(r, i){
var {a2h, i2p, q2x} = keys(i);
var cache = (
!r.cacheUrl ? '' :
'<span class="cache bracket"><a href="'+ r.cacheUrl + '" accesskey="'+
q2x +'">[cache]</a><kbd>'+ q2x +'</kbd></span>');
with(r) return String.concat(
'<li><button class="marker" id="', i, '" accesskey="',
a2h, '">', a2h, '</button><a class="title" href="',
unescapedUrl, '" accesskey="', i2p,
'"><img class="favicon" src="http://favicon.hatena.ne.jp/?url=',
encodeURIComponent(unescapedUrl), '"/>', title, '</a><kbd>', i2p,
'</kbd>', cache, '<span class="domain">', visibleUrl,
'</span><div class="content">', content, '</div></li>');
},
css: <![CDATA[ ]]>,
logo: gLogo,
})({
names: ['gimage', '|'],
desc: 'Google Images'.link(GImage) +' + multi-options + '+ GSgFAQ,
help: ''+ (
<ul>
<li>See <b>google</b> for preferences.</li>
<li>
Available options:
{[<><b>{k.split('_')[0]}</b>: {v}<br/></>
for([k, v] in new Iterator(GIOpts))]
.reduce(function(pre, kv) pre.appendChild(kv), <pre/>)}
(separate with commas/spaces to specify multiples)
</li>
</ul>),
top: GImage,
path: 'images',
api: 'http://www.google.com/uds/GimageSearch',
ds: 'i',
xargs: {modifier: NounGIOpts},
drsz: 'large',
list: function gi_list(r, i){
var {a2h, i2p} = keys(i);
with(r) return String.concat(
'<li style="width:', tbWidth, 'px"><label for="', i,
'"><button class="alpha" id="', i, '" accesskey="', a2h,
'">', a2h, '</button><img src="', tbUrl, '" alt="', contentNoFormatting,
'"></label><span class="size">', width, 'x', height, '</span> ',
'<a class="url" href="', originalContextUrl, '" accesskey="', i2p,
'"><img class="favicon alpha" src="http://favicon.hatena.ne.jp/?url=',
encodeURIComponent(originalContextUrl), '">', visibleUrl,
'</a> <kbd>', i2p, '</kbd></li>');
},
css: <![CDATA[
li {
display:inline-block; vertical-align:top; position: relative;
margin:0 1px 2px; padding:0; line-height:92%; max-width:50%;
}
.list {text-align:center; margin:2px 0}
.alpha {position:absolute; opacity:0.6}
.alpha[disabled] {display:none}
.favicon {top:0; right:0}
]]>,
logo: <img src={Google +'intl/en_ALL/images/images_hp.gif'} height="80"/>,
})({
names: ['gvideo', '^'],
desc: 'Google Video'.link(GVideo) +' + '+ GSgFAQ,
help: ''+ (
<ul>
<li>See <b>google</b> for preferences.</li>
</ul>),
top: GVideo,
path: 'videosearch',
api: 'http://www.google.com/uds/GvideoSearch',
ds: 'yt',
drsz: 'small',
xq: function gv_xq(q) q +' site:*',
list: function gv_list(r, i){
var {a2h, i2p, q2x} = keys(i);
var {url, playUrl} = r;
var [, top, domain] = /\?q=(https?:\/\/(?:www\.)?([^/]+))/(url) || ' ';
var play = (!playUrl ? '' :
'<a class="play bracket" href="'+ playUrl +'" accesskey="'+
q2x + '">[play]</a><kbd>'+ q2x +'</kbd>');
return String.concat(
'<li><button class="marker" id="', i, '" accesskey="', a2h, '">', a2h,
'</button><a class="title" href="', url, '" accesskey="', i2p,
'"><img class="favicon" src="http://favicon.hatena.ne.jp/?url=',
encodeURIComponent(top), '"/>', r.title,
'<img class="thumb" src="', r.tbUrl, '" alt="', r.titleNoFormatting,
'"></a><kbd>', i2p, '</kbd>', play, '<span class="domain">',
domain, '</span> <span class="duration">', fdurat(r.duration),
'</span><div class="content">', r.content, '</div></li>');
},
css: <![CDATA[
li {clear:right}
.thumb {float:right; max-height:72px}
.duration {font-size:88%}
]]>,
logo: (<div style="background-color:#fff;padding:4px 4px 0">
<img src="http://video.google.com/img/logo_videos.png"
border="none" height="40"/></div>),
});
0,function(){{}
const Name = 'gcode',
Base = '<style>'+ CSS + <![CDATA[
#refn {font:bold 92% sans-serif}
.refcontainer {display:inline-block; vertical-align:top}
pre {margin:1ex 1px; position:relative}
pre:hover {outline:solid 1px; -moz-outline-radius:6px}
pre button {position:absolute; top:0; left:0}
]]> +'</style>'+ <div class={Name}><div id={Name}
> </div><a href={GCode} class="logo" accesskey="^"
><img height="80" border="0"
src={Google +'intl/en/images/logos/code_search_logo_lg.gif'}/></a></div>;
var help = '...';
$.get(GCode, function gc_gothelp(htm){
help = /<table\s[^>]*\sid=examples[^]+?<\/table>/(htm) +'';
});
googleCommand({
names: [Name, ';'],
description: 'Google Code Search'.link(GCode),
argument: noun_arb_text,
execute: function gc_execute({object: {text}}){
Utils.openUrlInBrowser(GCode + (
text
? '?q='+ encodeURIComponent(text)
: '/advanced_code_search'));
},
preview: function gc_preview(pb, {object: {text}}){
var cn, q = text.trim();
while(!(cn = pb.ownerDocument.getElementById(Name))) pb.innerHTML = Base;
if(!q) return void(cn.innerHTML = help);
cn.className += ' loading';
CmdUtils.previewAjax(pb, {
url: GCode,
data: {q: q},
success: function gc_success(htm){
cn.innerHTML = /<div id=results[^]+?(?=<div id=navbar)/(htm);
var doc = cn.ownerDocument, i = 9;
for each(let pre in Array.slice(cn.getElementsByTagName('pre'))){
pre.removeAttribute('onmouseout');
pre.removeAttribute('onmouseover');
pre.code = pre.getAttribute('onclick');
pre.onclick = preClick;
let b = doc.createElement('button');
b.textContent = b.accessKey = (++i).toString(36);
pre.insertBefore(b, pre.firstChild);
tie(pre, buttonFocus);
}
cn.className = '';
},
error: ngx(cn),
});
},
});
function preClick(){
Utils.openUrlInBrowser(GCode + /\/p\?[^\']+/(this.code));
}
function buttonFocus(){
this.parentNode.onclick();
}
}();
0,function(){{}
const Name = 'gmail',
Base = '<style>'+ CSS + <![CDATA[
dd {margin:0.2em 0 0.8em 1em}
em {line-height:1.8}
.fullcount {font-weight:bolder}
]]> +'</style>'+ <div class={Name}><div id={Name}
class="loading"> </div><a href={Gmail} class="logo" accesskey="^"
><img width="143" height="59" border="0" src="http://www.google.com/mail/help/images/logo1.gif"/></a></div>;
var sent;
function reset(){ sent = false }
googleCommand({
names: [Name, '@'],
icon: Gmail +'images/favicon.ico',
description: 'Checks/opens/composes '+ 'Gmail'.link(Gmail),
arguments: {'object @': noun_type_contact},
execute: function gm_execute({object: {text: addr}}){
var {title, URL} = CmdUtils.getDocument(), me = this, [tab] =
Utils.tabs.search(/^https?:\/\/mail\.google\.com\/mail\/(?:[?#]|$)/);
if(!tab){
Utils.openUrlInBrowser(Gmail + (addr ? Utils.paramsToString({
su: title, to: addr, body: this._txt(URL), fs:1, tf:1, view: 'cm',
}) : ''));
return;
}
var {gmonkey} = tab.document.defaultView.wrappedJSObject;
if(gmonkey) gmonkey.load('1.0', function gm_load(gmail){
try {
if(gmail.getActiveViewType() !== 'co'){
var [cm] = $('span[role="link"]', gmail.getNavPaneElement());
var ev = cm.ownerDocument.createEvent('Events');
ev.initEvent('click', true, false);
cm.dispatchEvent(ev);
}
var $v = ($(gmail.getActiveViewElement())
.find('textarea[name="to"]').val(addr).end()
.find('input:first').val(title).end()),
[ifr] = $v.find('iframe');
(ifr
? ifr.contentDocument.execCommand('insertHTML', false, me._htm(URL))
: $v.find('textarea[name="body"]').val(me._txt(URL)));
Utils.setTimeout(function(){ gtab.focus() });
} catch(e){ me._say('Error in Gmail manipulation.', e) }
});
else this._say('Failed to grab Gmail API.');
},
preview: function gm_preview(pb){
if(sent && pb.ownerDocument.getElementById(Name)) return;
pb.innerHTML = Base;
sent = true;
var me = this;
$.ajax({
url: Gmail +'feed/atom',
dataType: 'text',
success: function gm_success(atom){
var cn = pb.ownerDocument.getElementById(Name);
if(!cn) return;
var x = xml(atom);
if(!x) return ng(cn, 'Error parsing Atom.');
cn.innerHTML = me._lst(x);
cn.className = '';
listenOnce(context.chromeWindow.gUbiquity.msgPanel,
'popuphidden', reset, false);
}});
},
_say: function gm__say(msg, err){
displayMessage({text: msg, exception: err}, this);
},
_txt: function gm__txt(u) u +'\n'+ CmdUtils.getSelection(),
_htm: function gm__htm(u)(
<a href={u}>{u}</a> + <br/> + CmdUtils.getHtmlSelection()),
_lst: function gm__lst(feed){
var num = +feed.fullcount.text();
if(!num) return '<em>No new mail.</em>';
var dl = <dl/>, i = 0, k;
for each(var e in feed.entry)
dl.appendChild(
<dt/>.appendChild(
(<kbd>{k = (++i).toString(36)}</kbd>) +
(<a class="title" accesskey={k}
href={[email protected](/^http/, '$&s')}>{e.title +''}</a>)) +
<dd/>.appendChild(
<div class="author"/>.appendChild(
(<a href={'mailto:'+ e.author.email}>{e.author.name +''}</a>) +
(<span class="issued">
({(e.issued +'').replace(/[TZ]/g, ' ').trim()})</span>)) +
(<div class="summary">{e.summary +''}</div>)));
return rawxml(
<div class="fullcount"/>.appendChild(
(<b>{num}</b>) +
(<span> new mail{num > 1 ? 's' : ''}</span>)) +
dl);
},
});
}();
googleCommand({
names: ['greader', ','],
description: (
'Lists up the page feeds and queries '+
'Google Reader'.link(GReader) + ' for their subscriber counts.'),
icon: Google +'reader/ui/favicon.ico',
execute: GReader,
preview: function gr_preview(pb){
var me = this, links =
CmdUtils.getDocument().querySelectorAll('link[rel="alternate"]');
CmdUtils.previewList(
pb, Array.map(links, me._list),
function(i)(me._open(links[i].href), true), me._css);
pb.appendChild(pb.ownerDocument.createElement('div')).innerHTML =
<a class="logo" href={GReader} accesskey="^"/>.appendChild(
<img src={'http://gmodules.com/ig/images/plus_google.gif'}
border="0"/>);
Array.forEach(pb.getElementsByClassName('feed'), me._peek, pb);
},
_open: function gr__open(u){
Utils.openUrlInBrowser(GReader +'view/feed/'+ encodeURIComponent(u));
},
_list: function gr__list(l){
var a = <a class="link" href={l.href}>{l.title}</a>;
var f = /\b(?:rss|atom|xml)\b/i(l.type);
if(f) a.@class += ' feed';
return a + <span class="type">({f || l.type})</span>;
},
_peek: function gr__peek(a){
var s = a.ownerDocument.createElement('span');
s.className = 'count';
s.textContent = '-';
a.parentNode.insertBefore(s, a.nextSibling);
CmdUtils.previewAjax(this, {
url: GReader +'directory/search?hl=en&q='+ encodeURIComponent(a.href),
success: function gr__success(h){
if(/class="number">(.*)<\/span>\s*<div>subscriber/.test(h))
s.textContent = +RegExp.$1.replace(/\D+/g, '');
s.className += ' complete';
},
});
},
_css: <![CDATA[
.type {font-size:92%}
.count {
display:inline-block; outline:solid 1px; -moz-outline-radius:4px;
font:bold 92% sans-serif; padding:0 0.3em}
.link {margin-left:0.2em}
.count, .type {margin-left:0.5em}
.count:not(.complete) {opacity:0.7}
]]>,
});
const ChromeFans = 'http://www.chromefans.org/';
googleCommand({
name: 'grank',
description: ''+<>
Shows <a href="http://en.wikipedia.org/wiki/PageRank" accesskey="^"
>PageRank&#x2122;</a> of a URL.</>,
icon: ChromeFans +'favicon.ico',
argument: noun_type_url,
execute: Google +'corporate/tech.html',
preview: function pr_preview(pb, {object: {text: u}}){
this.previewDefault(pb);
if(!u) return;
CmdUtils.previewAjax(pb, {
url: ChromeFans +'pr/google.php?u='+ encodeURIComponent(u),
success: function pr_success(h){
pb.innerHTML = /<style[^]+?style>/(h) + /<table[^]+?table>/(h);
},
error: Utils.log,
});
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment