-
-
Save satyr/60561 to your computer and use it in GitHub Desktop.
google++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Utils.extend(feed, { | |
title: 'google++', | |
author: { | |
name: 'satyr', email: 'murky.satyr\x40gmail.com', | |
homepage: 'http://satyr.github.com', | |
}, | |
license: 'X', | |
}) | |
const | |
Google = 'https://www.google.com/', | |
GImages = 'https://image.google.com/', | |
GVideos = 'https://video.google.com/', | |
GMail = 'https://mail.google.com/mail/', | |
GBooks = 'https://books.google.com/', | |
GTranslate = 'https://translate.google.com/', | |
GBookmarks = 'https://www.google.com/bookmarks/', | |
GLogos = Google +'logos/', | |
Googl = 'http://goo.gl/', | |
IFLHelp = Google +'support/websearch/bin/answer.py?answer=30735', | |
Icon = 'chrome://ubiquity/skin/icons/google.ico', | |
PPath = 'extensions.ubiquity.google.', | |
PLang = PPath +'lang', | |
PFrom = PPath +'from', | |
PLogo = PPath +'logo', | |
{escapeHtml: H, prefs: Prefs} = Utils, | |
CSS = ` | |
body {position:relative; line-height:1.23} | |
li {margin-bottom:0.2em} | |
em {line-height:1.8} | |
a img {border:none; vertical-align:middle} | |
kbd {text-decoration:underline; margin:-1px 4px 0 1px} | |
input[type=button] {padding:0; border-width:1px; cursor:pointer} | |
input[type=button][disabled] {cursor:inherit} | |
input[type=button], kbd {font:bold 92% monospace} | |
input[type=button].active {background-color:transparent; color:inherit} | |
input[type=button].number[disabled] {text-decoration:underline} | |
h2 a[accesskey]::before, h3 a[accesskey]::before { | |
content:attr(accesskey); margin-right:0.2em; padding:0 2px; | |
font:bold 92% monospace; text-transform:uppercase; | |
border:1px solid; border-radius:4px} | |
.list {list-style:none; padding:0; margin:0} | |
.pagination {text-align:center; font-size:111%} | |
.marker {margin-right:3px; vertical-align:bottom} | |
.content {font-size:96%} | |
.error {font-style:oblique; line-height:1.8} | |
.logo {display:inline-block} | |
.logo, .logo > img {vertical-align:middle} | |
.loading {opacity:0.9} | |
.loading + .logo {opacity:0.4} | |
.error + .logo {opacity:0.7} | |
.cite {font-style:italic} | |
`, | |
CSSLogo = 'background-color:#fff;padding:4px 4px 0', | |
Langs = noun_type_lang_google._list | |
.reduce((o, s) => (o[s.text] = s.data, o), {'*': ''}), | |
Regions = kv2vk({'':'*',AF:'Afghanistan',AL:'Albania',DZ:'Algeria',AS:'American Samoa',AD:'Andorra',AO:'Angola',AI:'Anguilla',AQ:'Antarctica',AG:'Antigua and Barbuda',AR:'Argentina',AM:'Armenia',AW:'Aruba',AU:'Australia',AT:'Austria',AZ:'Azerbaijan',BS:'Bahamas',BH:'Bahrain',BD:'Bangladesh',BB:'Barbados',BY:'Belarus',BE:'Belgium',BZ:'Belize',BJ:'Benin',BM:'Bermuda',BT:'Bhutan',BO:'Bolivia',BA:'Bosnia and Herzegovina',BW:'Botswana',BV:'Bouvet Island',BR:'Brazil',IO:'British Indian Ocean Territory',VG:'British Virgin Islands',BN:'Brunei',BG:'Bulgaria',BF:'Burkina Faso',BI:'Burundi',KH:'Cambodia',CM:'Cameroon',CA:'Canada',CV:'Cape Verde',KY:'Cayman Islands',CF:'Central African Republic',TD:'Chad',CL:'Chile',CN:'China',CX:'Christmas Island',CC:'Cocos Islands',CO:'Colombia',KM:'Comoros',CG:'Congo - Brazzaville',CD:'Congo - Kinshasa',CK:'Cook Islands',CR:'Costa Rica',HR:'Croatia',CU:'Cuba',CY:'Cyprus',CZ:'Czech Republic',DK:'Denmark',DJ:'Djibouti',DM:'Dominica',DO:'Dominican Republic',EC:'Ecuador',EG:'Egypt',SV:'El Salvador',GQ:'Equatorial Guinea',ER:'Eritrea',EE:'Estonia',ET:'Ethiopia',FK:'Falkland Islands',FO:'Faroe Islands',FJ:'Fiji',FI:'Finland',FR:'France',GF:'French Guiana',PF:'French Polynesia',TF:'French Southern Territories',GA:'Gabon',GM:'Gambia',GE:'Georgia',DE:'Germany',GH:'Ghana',GI:'Gibraltar',GR:'Greece',GL:'Greenland',GD:'Grenada',GP:'Guadeloupe',GU:'Guam',GT:'Guatemala',GN:'Guinea',GW:'Guinea-Bissau',GY:'Guyana',HT:'Haiti',HM:'Heard Island and McDonald Islands',HN:'Honduras',HK:'Hong Kong SAR China',HU:'Hungary',IS:'Iceland',IN:'India',ID:'Indonesia',IR:'Iran',IQ:'Iraq',IE:'Ireland',IL:'Israel',IT:'Italy',CI:'Ivory Coast',JM:'Jamaica',JP:'Japan',JO:'Jordan',KZ:'Kazakhstan',KE:'Kenya',KI:'Kiribati',KW:'Kuwait',KG:'Kyrgyzstan',LA:'Laos',LV:'Latvia',LB:'Lebanon',LS:'Lesotho',LR:'Liberia',LY:'Libya',LI:'Liechtenstein',LT:'Lithuania',LU:'Luxembourg',MO:'Macau SAR China',MK:'Macedonia',MG:'Madagascar',MW:'Malawi',MY:'Malaysia',MV:'Maldives',ML:'Mali',MT:'Malta',MH:'Marshall Islands',MQ:'Martinique',MR:'Mauritania',MU:'Mauritius',YT:'Mayotte',MX:'Mexico',FM:'Micronesia',MD:'Moldova',MC:'Monaco',MN:'Mongolia',MS:'Montserrat',MA:'Morocco',MZ:'Mozambique',MM:'Myanmar',NA:'Namibia',NR:'Nauru',NP:'Nepal',NL:'Netherlands',AN:'Netherlands Antilles',NC:'New Caledonia',NZ:'New Zealand',NI:'Nicaragua',NE:'Niger',NG:'Nigeria',NU:'Niue',NF:'Norfolk Island',KP:'North Korea',MP:'Northern Mariana Islands',NO:'Norway',OM:'Oman',PK:'Pakistan',PW:'Palau',PS:'Palestinian Territory',PA:'Panama',PG:'Papua New Guinea',PY:'Paraguay',PE:'Peru',PH:'Philippines',PN:'Pitcairn',PL:'Poland',PT:'Portugal',PR:'Puerto Rico',QA:'Qatar',RE:'Reunion',RO:'Romania',RU:'Russia',RW:'Rwanda',SH:'Saint Helena',KN:'Saint Kitts and Nevis',LC:'Saint Lucia',PM:'Saint Pierre and Miquelon',VC:'Saint Vincent and the Grenadines',WS:'Samoa',SM:'San Marino',ST:'Sao Tome and Principe',SA:'Saudi Arabia',SN:'Senegal',YU:'Serbia',SC:'Seychelles',SL:'Sierra Leone',SG:'Singapore',SK:'Slovakia',SI:'Slovenia',SB:'Solomon Islands',SO:'Somalia',ZA:'South Africa',GS:'South Georgia and the South Sandwich Islands',KR:'South Korea',ES:'Spain',LK:'Sri Lanka',SD:'Sudan',SR:'Suriname',SJ:'Svalbard and Jan Mayen',SZ:'Swaziland',SE:'Sweden',CH:'Switzerland',SY:'Syria',TW:'Taiwan',TJ:'Tajikistan',TZ:'Tanzania',TH:'Thailand',TG:'Togo',TK:'Tokelau',TO:'Tonga',TT:'Trinidad and Tobago',TN:'Tunisia',TR:'Turkey',TM:'Turkmenistan',TC:'Turks and Caicos Islands',TV:'Tuvalu',VI:'U.S. Virgin Islands',UG:'Uganda',UA:'Ukraine',AE:'United Arab Emirates',GB:'United Kingdom',US:'United States',UM:'United States Minor Outlying Islands',UY:'Uruguay',UZ:'Uzbekistan',VU:'Vanuatu',VA:'Vatican',VE:'Venezuela',VN:'Vietnam',WF:'Wallis and Futuna',EH:'Western Sahara',YE:'Yemen',ZM:'Zambia',ZW:'Zimbabwe'}), | |
NewsEditions = kv2vk({au:'Australia',in:'India',en_il:'Israel',en_my:'Malaysia',nz:'New Zealand',en_pk:'Pakistan',en_ph:'Philippines',en_sg:'Singapore',ar_me:'\u0627\u0644\u0639\u0627\u0644\u0645 \u0627\u0644\u0639\u0631\u0628\u064A (Arab world)',ar_ae:'\u0627\u0644\u0625\u0645\u0627\u0631\u0627\u062A (UAE)',ar_lb:'\u0644\u0628\u0646\u0627\u0646 (Lebanon)',ar_sa:'\u0627\u0644\u0633\u0639\u0648\u062F\u064A\u0629 (KSA)',cn:'\u4E2D\u56FD\u7248 (China)',hk:'\u9999\u6E2F\u7248 (Hong Kong)',hi_in:'\u092D\u093E\u0930\u0924 (India)',ta_in:'\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (India)',ml_in:'\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (India)',te_in:'\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (India)',iw_il:'\u05D9\u05E9\u05E8\u05D0\u05DC (Israel)',jp:'\u65E5\u672C (Japan)',kr:'\uD55C\uAD6D (Korea)',tw:'\u53F0\u7063\u7248 (Taiwan)',vi_vn:'Vi\u1EC7t Nam (Vietnam)',nl_be:'Belgi\xEB',fr_be:'Belgique',en_bw:'Botswana',de:'Deutschland',es:'Espa\xF1a',en_et:'Ethiopia',fr:'France',en_gh:'Ghana',en_ie:'Ireland',it:'Italia',en_ke:'Kenya',hu_hu:'Magyarorsz\xE1g',en_na:'Namibia',nl_nl:'Nederland',en_ng:'Nigeria',no_no:'Norge',de_at:'\xD6sterreich',pl_pl:'Polska','pt-PT_pt':'Portugal',de_ch:'Schweiz',fr_sn:'S\xE9n\xE9gal',en_za:'South Africa',fr_ch:'Suisse',sv_se:'Sverige',en_tz:'Tanzania',tr_tr:'T\xFCrkiye',en_ug:'Uganda',uk:'U.K.',en_zw:'Zimbabwe',ar_eg:'\u0645\u0635\u0631 (Egypt)',el_gr:'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1 (Greece)',ru_ru:'\u0420\u043E\u0441\u0441\u0438\u044F (Russia)',ru_ua:'\u0423\u043A\u0440\u0430\u0438\u043D\u0430 (Ukraine)',uk_ua:'\u0423\u043A\u0440\u0430\u0457\u043D\u0430 (Ukraine)',es_ar:'Argentina','pt-BR_br':'Brasil',ca:'Canada English',fr_ca:'Canada Fran\xE7ais',es_cl:'Chile',es_co:'Colombia',es_cu:'Cuba',es_us:'Estados Unidos',es_mx:'M\xE9xico',es_pe:'Per\xFA',us:'U.S.',es_ve:'Venezuela'}), | |
NewsTopics = kv2vk({'':'Top Stories',ss:'Starred',w:'World',n:'U.S.',b:'Business',t:'Sci/Tech',e:'Entertainment',s:'Sports',m:'Health',ir:'Spotlight',po:'Most Popular'}), | |
NounSiteSearch = { | |
name: 'google site search', | |
label: 'site', | |
suggest: function gss_suggest(txt, htm, cb, sx){ | |
if(sx || !(txt = txt.trim())) return []; | |
var paths = [], ltrim = /\/[^/]*$/, rtrim = /^[^.]*.?/, exact; | |
var [, site] = /^\w+:\/+([^?#]*)/.exec(CmdUtils.window.location) || [, '']; | |
while(site !== (site = site.replace(ltrim, '')) || | |
(site = site.replace(rtrim, ''))){ | |
if(site === txt) exact = true; | |
paths.push(CmdUtils.makeSugg(site)); | |
} | |
var ss = CmdUtils.grepSuggs(txt, paths); | |
exact || ss.push(CmdUtils.makeSugg(txt, null, null, .25)); | |
return ss; | |
}, | |
}, | |
NounRegion = CmdUtils.NounType('region', Regions) | |
NounRegion.noSelection = true | |
function GoogleCommand(u, o){ | |
const [Name] = o.names || [o.name] | |
, Base = | |
'<style>'+ CSS + [o._css] +'</style>'+ | |
'<div class="'+ Name +'">'+ | |
'<div id="'+ Name +'"></div>'+ | |
'<a class=logo href="'+ u +'" accesskey="/">'+ o._logo +'</a>'+ | |
'</div>' | |
delete o._css | |
delete o._logo | |
o._content = function gcmd_content(pb, cb){ | |
var cn | |
while(!(cn = pb.ownerDocument.getElementById(Name))){ | |
pb.innerHTML = Base | |
cb && cb.call(this) | |
} | |
return cn | |
} | |
o.url = u | |
'execute' in o || (o.execute = '_url' in o ? execute : u) | |
'preview' in o || (o.preview = preview) | |
'icon' in o || (o.icon = Icon) | |
return CmdUtils.CreateCommand(o) | |
} | |
function execute(args){ | |
Utils.openUrlInBrowser(this._url(args) || this._durl || this.url); | |
} | |
function preview(pb, args){ | |
var cn = this._content(pb), u = this._url(args); | |
u && cjax(cn, {url: u, pry: this._pry, fix: this._fix}); | |
} | |
function cjax(cn, opts){ | |
var {url, dat, pry, fix, typ} = opts; | |
cn.className = 'loading'; | |
return CmdUtils.previewAjax(cn.ownerDocument.body, { | |
url: url, data: dat || null, dataType: typ || 'text', | |
success: function g_success(res){ | |
pry && ok(cn, pry(res)); | |
fix && fix(cn, res, opts); | |
}, | |
error: ngx(cn), | |
}); | |
} | |
function pjax(o, pb){ | |
return pb ? CmdUtils.previewAjax(pb, o) : $.ajax(o) | |
} | |
function tie(it, fn, me){ | |
it && it.addEventListener('click', function tied(e){ | |
var b = e.target; | |
if(b.type !== 'button') return; | |
e.preventDefault(); | |
fn.call(me, kick(b)); | |
}, false); | |
} | |
function kick(b){ | |
b.disabled = true; | |
b.className += ' active'; | |
return b; | |
} | |
function ok(c, it){ | |
if(!it) return; | |
if(typeof it.jquery == 'string'){ | |
c.innerHTML = ''; | |
it.appendTo(c); | |
} else c.innerHTML = it; | |
c.className = ''; | |
c.ownerDocument.defaultView.scrollTo(0, 0); | |
} | |
function ng(c){ | |
c.textContent = Array.slice(arguments, 1).join(' '); | |
c.className = 'error'; | |
} | |
function ngx(c){ | |
return function g_erjax(x){ if(x.status) ng(c, x.status, x.statusText) } | |
} | |
function btn(klass, key, attrs){ | |
var h = `<input type=button | |
class="${klass}" accesskey="${H(key)}" value="${H(key)}"` | |
for(let k in attrs) h += ` ${k}="${H(attrs[k])}"` | |
return h +'/>' | |
} | |
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, | |
start: 0, | |
hl: args.format .data || Prefs.get(PLang, ''), | |
gl: args.location.data || Prefs.get(PFrom, ''), | |
}; | |
return ps; | |
} | |
function fdur(s){ return (s / 60 | 0) +':'+ (s % 60 + 100 + '').slice(-2) } | |
function qse(lm, sl, fn, me){ | |
return Array.forEach(lm.querySelectorAll(sl), fn, me) | |
} | |
function ul(){ | |
return '<ul><li>'+ Array.join(arguments, '</li><li>') +'</li></ul>' | |
} | |
function kv2vk(o){ | |
for(var [k, v] in new Iterator(o)) delete o[k], o[v] = k; | |
return o; | |
} | |
function opener(u){ return () => Utils.openUrlInBrowser(u) } | |
function logosrc(name){ return Google +'images/logos/'+ name +'.gif' } | |
function logoimg(name){ | |
return '<img style="'+ CSSLogo +'" src="'+ logosrc(name) +'">' | |
} | |
function destyle(lmn){ | |
for(let l of lmn.querySelectorAll('[style]')) l.removeAttribute('style') | |
} | |
function unweblight(a){ | |
var u = Utils.urlToParams(a.href).q || a.href | |
if(/^https?:\/\/googleweblight.com\/\?/.test(u)) | |
u = Utils.urlToParams(u).lite_url | |
a.href = u | |
return a | |
} | |
const Doodle = {} | |
function loget(){ | |
var d = Date.now() | |
if(d - loget.last < 20 * 6e4) return | |
loget.last = d | |
$.ajax({url: Google +'doodles/doodles.xml', dataType: 'xml', success: logot}) | |
} | |
function logot(xml){ | |
var dscs = xml.getElementsByTagName('description') | |
, num = dscs.length - 1 | |
, i = 1 + num * Math.pow(Math.random(), 2) | 0 | |
, $dsc = $(dscs[i].textContent.trim()) | |
, img = $dsc.find('img')[0].cloneNode() | |
img.src = img.src.replace(/^\w*:?(?=\/\/)/, 'http:') | |
Doodle.img = img | |
Doodle.title = | |
xml.getElementsByTagName('title')[i].textContent + | |
$dsc.find('strong')[0].nextSibling.nodeValue | |
} | |
loget() | |
function GSearchCommand(top, {tbm, selector, names, description, list, css}){ | |
var [Name] = names | |
, Style = '<style>'+ CSS + css +'</style>' | |
, Base = | |
'<div class="'+ Name +'"><div id="'+ Name +'"></div>'+ | |
'<a class="logo" accesskey="/" href="'+ top + | |
'"><img src=https://www.google.com/images/logo.png height=80></a></div>' | |
CmdUtils.CreateCommand({ | |
names, | |
description: description.link(top), | |
icon: Icon, | |
arguments: { | |
object: noun_arb_text, | |
format: noun_type_lang_google, | |
location: NounRegion, | |
source: NounSiteSearch, | |
}, | |
execute: function gs_execute(args){ | |
var ps = params(args), u = top | |
if(ps){ | |
u = Google +'search'+ Utils.paramsToString(ps) | |
if(tbm) u += '&tbm='+ tbm | |
} | |
Utils.openUrlInBrowser(u) | |
}, | |
preview: function gs_preview(pb, args){ | |
var cn, ps = params(args) | |
while(!(cn = pb.ownerDocument.getElementById(Name))){ | |
pb.innerHTML = Style + Base | |
let logo = pb.querySelector('.logo') | |
if(Prefs.get(PLogo, true)){ | |
if(Doodle.img){ | |
logo.innerHTML = '' | |
logo.appendChild(Doodle.img.cloneNode()) | |
logo.title = Doodle.title | |
} | |
loget() | |
} else logo.style.display = 'none' | |
} | |
if(!ps) return | |
if(tbm) ps.tbm = tbm | |
var starts = [] | |
, ojax = { | |
url: Google +'search', | |
data: ps, | |
headers: { | |
'User-Agent': 'DoCoMo/2.0 N01C(c500;TB;W24H17)', | |
}, | |
success: function gs_success(htm, st, xhr){ | |
var doc = xhr.responseXML | |
, nfo = doc.querySelector('#topbar + div:not([id])') | |
, rs = doc.querySelectorAll(selector) | |
, h = '' | |
if(nfo) | |
h += nfo.outerHTML | |
h += '<div class="pagination">' | |
if(ps.start) | |
h += btn('navi', '<') | |
if(rs.length) | |
h += `<b> ${ps.start + 1} ~ ${ps.start + rs.length} </b>` | |
if(xhr.responseXML.querySelector('#navbar > b')) | |
h += btn('navi', '>') | |
h += '</div><ul class="list">' | |
var i = -1, alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
for(let r of rs){ | |
destyle(r) | |
h += list(r, ++i, alpha[i]) | |
} | |
h += '</ul>' | |
ok(cn, h) | |
tie(cn.querySelector('.list'), b => { | |
Utils.openUrlInBrowser(b.getAttribute('url')) | |
}) | |
tie(cn.querySelector('.pagination'), b => { | |
if(b.value == '<') | |
ps.start = starts.pop() || 0 | |
else { | |
starts.push(ps.start) | |
ps.start += rs.length | |
} | |
ojax.data = ps | |
pjax(ojax, pb) | |
}) | |
}, | |
error: ngx(cn), | |
} | |
pjax(ojax, pb) | |
}, | |
previewDelay: 0, | |
}) | |
} | |
GSearchCommand(Google, { | |
names: ['google', '/'], | |
description: 'Google Web Search', | |
selector: '.web_result', | |
list: function g_list(wr, id, alpha){ | |
var a = unweblight(wr.querySelector('a')) | |
, div = wr.children[1] | |
return `<li>${btn('marker', alpha, {id, url: a.href})} | |
${a.outerHTML + div.outerHTML}` | |
}, | |
css: ` | |
.logo[title]::after { | |
content:attr(title); display:inline-block; padding:0 2px; | |
position:absolute; bottom:1px; left:1px; z-index:2; | |
opacity:0.6; color:#fff; background-color:#666; | |
font:bolder smaller sans-serif; border-radius:6px} | |
`, | |
}) | |
GSearchCommand(GImages, { | |
names: ['gimages', '|'], | |
description: 'Google Images', | |
tbm: 'isch', | |
selector: '.image', | |
list: function gi_list(a, id, alpha){ | |
a.href = Utils.urlToParams(a.href).imgurl | |
a.children[0].removeAttribute('height') | |
return `<li>${btn('knob', alpha, {id, url: a.href})}${a.outerHTML}` | |
}, | |
css: ` | |
li { | |
display:inline-block; vertical-align:top; position:relative; | |
margin:0 1px 2px; padding:0; line-height:92%; | |
min-width:12%; max-width:49%} | |
.list {text-align:center; margin:2px 0} | |
.knob {position:absolute; top:0; left:0; opacity:0.7} | |
.knob[disabled] {display:none} | |
`, | |
}) | |
GSearchCommand(GVideos, { | |
names: ['gvideos', '^'], | |
description: 'Google Videos', | |
tbm: 'vid', | |
selector: '.video_result', | |
list: function gv_list(vr, id, alpha){ | |
var a = unweblight(vr.querySelector('a')) | |
return `<li>${btn('marker', alpha, {id, url: a.href})} | |
${vr.querySelector('img').outerHTML}${a.outerHTML}<br> | |
${vr.querySelector('.metadata').outerHTML}<br> | |
${vr.querySelector('.cite').outerHTML}` | |
}, | |
css: ` | |
li {clear:both} | |
.list img {float:right} | |
` | |
}) | |
GoogleCommand(GMail, { | |
names: ['gmail', '@'], | |
icon: 'https://ssl.gstatic.com/ui/v1/icons/mail/images/favicon5.ico', | |
description: 'Checks/Opens/Composes '+ 'Gmail'.link(GMail) +'.', | |
help: 'Use the buttons to read, archive or mark-as-spam mails inline.', | |
arguments: {'object @': { | |
__proto__: noun_type_contact, | |
suggest: function ntc_hacked_suggest(t, h, c, s){ | |
if(s && s[1] && t.length < 3) return | |
return noun_type_contact.suggest.apply(this, arguments) | |
}, | |
}}, | |
execute: function gmail_execute({object: {text: addr}}){ | |
if(!addr) return void Utils.openUrlInBrowser(GMail +'#search/l:^u') | |
var {title, URL} = CmdUtils.document | |
Utils.openUrlInBrowser(GMail + Utils.paramsToString({ | |
su: title, to: addr, body: this._txt(URL), fs:1, tf:1, view: 'cm', | |
})) | |
}, | |
preview: function gmail_preview(pb){ | |
var me = this, cn = this._content(pb, gmail_reset) | |
if(me._checked) return | |
me._checked = true | |
cn.className = 'loading' | |
$.ajax({ | |
url: GMail +'feed/atom', dataType: 'text', | |
success: function gmail_success(atom){ | |
var x = new DOMParser().parseFromString(atom, 'application/xml') | |
if(x.nodeName == 'parsererror') return ng(cn, 'Error parsing Atom.') | |
ok(cn, me._lst(x)) | |
tie(cn.querySelector('dl'), me._act, me) | |
Utils.listenOnce( | |
context.chromeWindow.gUbiquity.panel, 'popuphidden', gmail_reset) | |
}, | |
}) | |
function gmail_reset(){ me._checked = false } | |
}, | |
_txt: function gmail_txt(u){ return u +'\n\n'+ CmdUtils.getSelection() }, | |
_lst: function gmail_lst(feed){ | |
var num = +feed.querySelector('fullcount').textContent | |
if(!num) return '<em>No new mail.</em>' | |
var action = (val, act, key) => | |
'<input type=button act='+ act +' accesskey='+ (key || '_') + | |
' value="'+ val + (key ? '['+ key +']': '') +'">' | |
var dl = '<dl>', i = 0 | |
for(let e of feed.querySelectorAll('entry')){ | |
let url = e.querySelector('link').getAttribute('href') | |
, kr = 'ABCDEFGHIJKL'[i] || '-' | |
, ka = 'MNOPQRSTUVWX'[i] | |
, ks = 'YZ1234567890'[i] | |
, author = e.querySelector('author') | |
, issued = e.querySelector('issued') | |
dl += '<div id="'+ H(/[?&]message_id=(\w+)/.exec(url)[1]) +'">' | |
+ '<dt><input type=button value='+ kr +' accesskey='+ kr +'>' | |
+ '<a class=title href="'+ H(url) +'">' | |
+ H(e.querySelector('title').textContent) +'</a></dt>' | |
+ '<dd>' | |
+ '<span class=author>' | |
+ '<a href="mailto:' | |
+ H(author.querySelector('email').textContent) +'">' | |
+ H(author.querySelector('name' ).textContent) +'</a>' | |
+ '<span class=issued>(' | |
+ H(issued.textContent.replace(/[TZ]/g, ' ').trim()) +')</span>' | |
+ '</span>' | |
+ '<span class=actions>' | |
+ action('Archive', 'arch', ka) | |
+ action('Spam', 'sp', ks) | |
+ '</span>' | |
+ '<div class=summary>' | |
+ H(e.querySelector('summary').textContent) +'</div>' | |
+ '</dd></div>' | |
i++ | |
} | |
return '<div class=fullcount><b>'+ num +'</b><span> new mail'+ | |
(num > 1 ? 's' : '') +'</span></div>' + dl +'</dl>' | |
}, | |
_act: function gmail_act(b){ | |
var me = this | |
if(!me._at){ | |
$.ajax({ | |
url: GMail +'h/_/', | |
success: function(h){ | |
me._at = /;at=([\w-]+)/.exec(h)[1] | |
me._act(b) | |
}, | |
}) | |
return | |
} | |
var $div = $(b).closest('div'), sm = $div.find('.summary')[0] | |
, {id} = $div[0], url = GMail +'h/_/', act = b.getAttribute('act') | |
if(act) $.post(url, {act: act, t: id, at: me._at}) | |
, sm.style.display = 'none' | |
else $.get(url, {v: 'c', th: id}, function(h){ | |
sm.style.opacity = 1 | |
sm.innerHTML = '<div class=content>'+ | |
/<div class=msg>[^]+?(?=<\/table>\s*<a name="m_")/.exec(h) +'</div>' | |
CmdUtils.absUrl(sm, url) | |
qse(sm, 'a', function(a){ | |
if(a.hostname == 'www.google.com' && a.pathname == '/url') | |
a.href = Utils.urlToParams(a.search).q | |
if(a.accessKey) | |
a.removeAttribute('accesskey') | |
}) | |
}, 'text'), sm.style.opacity = 0.5 | |
}, | |
_css: ` | |
dt {margin-left:0} | |
dd {margin:0.5ex 0 1ex} | |
.fullcount {margin-left:0.7em; font-weight:bolder} | |
.title {margin-left:0.2em} | |
.actions {float:right} | |
.content { | |
background-color:rgba(255,255,255,0.8) !important; | |
padding:4px; border-radius:1ex} | |
.content * | |
{color:#000 !important; background-color:transparent !important} | |
.content *:-moz-any-link {color:#33c !important} | |
.content *:-moz-any-link:visited {color:#00a !important} | |
`, | |
_logo: '<img src="http://www.google.com/mail/help/images/logo1.gif">', | |
}) | |
GoogleCommand(GBookmarks, { | |
name: 'gbookmarks', | |
description: 'Google Bookmarks'.link(GBookmarks) +' the current page.', | |
icon: GBookmarks +'api/static/images/favicon.ico', | |
arguments: {object_labels: noun_arb_text, instrument_notes: noun_arb_text}, | |
execute: function gbms_execute({ | |
object: {text: labels}, instrument: {text: notes}}){ | |
var {title, URL} = CmdUtils.document, me = this | |
if(!URL) return | |
title = title || URL | |
$.ajax({ | |
url: GBookmarks +'mark', dataType: 'text', | |
data: {op: 'edit', output: 'popup', bkmk: URL, title: title}, | |
success: function gbms_success(h){ | |
var [, sig] = /name=sig value="(\w+)"/.exec(h) || [] | |
if(!sig) return displayMessage({ | |
text: 'Failed to bookmark. Not logged in?', | |
onclick: opener(this.url), | |
}, me) | |
$.post(GBookmarks +'mark', { | |
sig: sig, bkmk: URL, title: title, | |
labels: labels, annotation: notes, | |
}, function gbms_post(){ | |
displayMessage({ | |
icon: me.icon, title: title, onclick: opener(GBookmarks), | |
text: URL + (labels && ' ['+ labels +']') + (notes && ' '+ notes), | |
}) | |
}) | |
}, | |
error: function gbms_error(x) { | |
return x.status && displayMessage(x.status +' '+ x.statusText, me) | |
}, | |
}) | |
}, | |
preview: function gbms_preview(pb, { | |
object: {text: labels}, instrument: {text: notes}}){ | |
var {title, URL} = CmdUtils.document, cn = this._content(pb) | |
if(!URL) return void this.previewDefault(cn) | |
var htm = '<h3 class="title"><a href="'+ H(URL) +'">'+ | |
H(title || URL) +'</a></h3>' | |
var lu = GBookmarks +'l#!view=threadsmgmt&fo=Starred&q=label:' | |
if(labels){ | |
htm += '<div class=labels>' | |
for(let lbl of labels.split(',').filter(Boolean).map(String.trim)) | |
htm += '<a href="'+ H(lu + encodeURIComponent(lbl)) +'">'+ | |
H(lbl) +'</a>' | |
htm += '</div>' | |
} | |
if(notes) htm += '<div class=notes>'+ H(notes) +'</div>' | |
cn.innerHTML = htm | |
}, | |
_css: '\ | |
.title {margin:1ex 0.5em}\ | |
.labels, .notes {padding:0 1em 1ex}\ | |
.labels > a {\ | |
dispaly:inline-block; border: 1px solid; border-radius:1em;\ | |
margin-right:0.5em; padding:0 0.5em;\ | |
}\ | |
.logo {background-color:#fff; border-radius:32px}\ | |
', | |
_logo: '<img src="'+ Google +'toolbar/ie/images/feature_bookmarks.gif">', | |
}) | |
CmdUtils.CreateCommand({ | |
name: 'gcache', | |
description: 'Opens the Google cache of a URL.', | |
icon: Icon, | |
argument: noun_type_url, | |
execute: function gcache_execute({object: {text}}){ | |
Utils.openUrlInBrowser( | |
'http://webcache.googleusercontent.com/search?q=cache:'+ | |
encodeURIComponent(text)) | |
}, | |
}) | |
GoogleCommand(Googl, { | |
name: 'gshorten', | |
description: 'Shortens a URL with '+ 'goo.gl'.link(Googl) +'.', | |
argument: noun_type_url, | |
execute: function gsh_execute({object: {text: u}}){ | |
if(!u) return | |
this._shorten(u, function gsh_e(s){ | |
CmdUtils.copyToClipboard(s) | |
~CmdUtils.selection.indexOf(u) && | |
CmdUtils.setSelection(Utils.escapeHtml(s), {text: s}) | |
displayMessage(s +' \u2190 '+ u, this) | |
}) | |
}, | |
preview: function gsh_preview(pb, {object: {text: u}}){ | |
var cn = this._content(pb) | |
if(!u || /^(?!https?:)/.test(u)) return ng(cn, '') | |
var hu = H(u) | |
ok(cn, '<pre class=old><a href="'+ hu +'">'+ hu +'</a></pre>') | |
this._shorten(u, function gsh_p(s){ | |
if(s === cn.querySelector('a').textContent) return | |
var hs = H(s) | |
$('.old', cn).animate({opacity: .5}) | |
$('<pre class=new style=display:none><a href="'+ hs +'">'+ hs + | |
'<br><br><img src="'+ hs +'.qr"></a></pre>') | |
.prependTo(cn).slideDown() | |
}, pb) | |
}, | |
_shorten: function gsh_shorten(u, cb, pb){ | |
if(u in this._bin) return cb.call(this, this._bin[u]) | |
var me = this | |
pjax({ | |
type: 'post', | |
url: 'https://www.googleapis.com/urlshortener/v1/url'+ | |
'?key=AIzaSyDm4gPhS_JVPaUtujcTkTC9jDnHbTXaMaw', | |
data: JSON.stringify({longUrl: u}), | |
processData: false, | |
contentType: 'application/json', | |
dataType: 'json', | |
success: function gsh_ok(o){ | |
return cb.call(me, me._bin[u] = o.id) | |
}, | |
error: function gsh_ng(x) { | |
return x.status && displayMessage(x.status +' '+ x.statusText, me) | |
}, | |
}, pb) | |
}, | |
_bin: {__proto__: null}, | |
_css: ` | |
pre {text-align:center} | |
.logo {font:bold 150% fantasy; margin:1px 2px} | |
`, | |
_logo: logoimg('url_shortener_logo'), | |
}) | |
CmdUtils.CreateCommand({ | |
name: 'gplusone', | |
icon: Icon, | |
description: "+1 to current page.", | |
argument: noun_type_url, | |
execute: function gp1_execute(){ | |
try { | |
var doc = this._doc.get() | |
doc.defaultView[0].document.getElementById('button').click() | |
} catch(e if e.name === 'TypeError'){ | |
var error = 'failed to +1' | |
Utils.reportInfo(this.name +': '+ e) | |
} | |
displayMessage(error || doc._url, this) | |
}, | |
preview: function gp1_preview(pb, {object: {text}}){ | |
if(!text) return void this.previewDefault(pb) | |
pb.parentNode.removeChild(pb.ownerDocument.head) | |
var script = pb.ownerDocument.createElement('script') | |
pb.innerHTML = '<g:plusone size=tall>' | |
pb.firstChild.setAttribute('href', text) | |
script.src = 'https://apis.google.com/js/platform.js' | |
doc = pb.appendChild(script).ownerDocument | |
doc ._url = text | |
this._doc = Cu.getWeakReference(doc) | |
}, | |
previewUrl: 'https://google.com/404', | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment