Skip to content

Instantly share code, notes, and snippets.

@jasherai
Forked from satyr/google++.ubiq.js
Created March 8, 2009 10:38
Show Gist options
  • Save jasherai/75721 to your computer and use it in GitHub Desktop.
Save jasherai/75721 to your computer and use it in GitHub Desktop.
const Google = 'http://google.com/',
PLang = 'extensions.ubiquity.google.lang',
PFrom = 'extensions.ubiquity.google.from',
PSafe = 'extensions.ubiquity.google.safe',
PSize = 'extensions.ubiquity.google.size',
{prefs} = Application,
ID = '#_'+ (Math.random() +'').slice(2),
Logo = <a class="logo" href={Google}><img border="0"
src={Google +'intl/en_ALL/images/logo.gif'} height="110"/></a>,
Base = <div class="google"><style><![CDATA[
@{position:relative; line-height:1.25}
@ul {list-style:none; padding:0; margin:0}
@li {margin-bottom:0.4em}
@button {padding:0; border-width:1px}
@button[disabled]{background-color:transparent; color:inherit}
@li button {margin-right:3px; vertical-align:bottom}
@kbd {text-decoration:underline; margin:0 3px 0 1px}
@button, @kbd {font:bold 92% "Consolas", monospace}
@.count {position:absolute; right:4px}
@.pagination {text-align:center}
@.logo {display:block}
@.error {font-style:oblique; line-height:1.8}
@.loading + .logo {opacity:0.4}
@.error + .logo {opacity:0.7}
]]></style><div id={ID.slice(1)}
/></div>.toXMLString().replace(/@/g, '.google '),
Langs = {
all: '',
Arabic: 'ar',
Bulgarian: 'bg',
Catalan: 'ca',
'Chinese (Simplified)': 'zh_CN',
'Chinese (Traditional)': 'zh_TW',
Croatian: 'hr',
Czech: 'cs',
Danish: 'da',
Dutch: 'nl',
English: 'en',
Estonian: 'et',
Filipino: 'tl',
Finnish: 'fi',
French: 'fr',
German: 'de',
Greek: 'el',
Hebrew: 'iw',
Hindi: 'hi',
Hungarian: 'hu',
Icelandic: 'is',
Indonesian: 'id',
Italian: 'it',
Japanese: 'ja',
Korean: 'ko',
Latvian: 'lv',
Lithuanian: 'lt',
Norwegian: 'no',
Polish: 'pl',
Portuguese: 'pt',
Romanian: 'ro',
Russian: 'ru',
Serbian: 'sr',
Slovak: 'sk',
Slovenian: 'sl',
Spanish: 'es',
Swedish: 'sv',
Thai: 'th',
Turkish: 'tr',
Ukrainian: 'uk',
Urdu: 'ur',
Vietnamese: 'vi',
},
Regions = {
any: '',
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',
};
var entry, logot;
CmdUtils.CreateCommand({
name: "google",
icon: Google +'favicon.ico',
takes: {'?': {_name: 'google-suggest', suggest: function(txt, htm, cb){
jQuery.getJSON(
Google +'complete/search?json&hl='+ prefs.getValue(PLang, '') +
'&q='+ encodeURIComponent(txt),
function([, qs, ns]){
qs.length && cb(qs.map(function(q, i)({
text: q, summary: q +' '+ ns[i].small()}))) });
return [{text: txt, summary: txt}];
}}},
modifiers: {
in: gnoun('language', Langs),
//from: gnoun('region', Regions),
},
description: ''+<><a href={Google}>google</a> + multi-page +
<a href="http://labs.google.com/suggestfaq.html">suggest</a></>,
help: ''+[
[<a href={Google +'language_tools'}>Language</a>,
PLang, Langs, ''],
[<>Region</>,
PFrom, Regions, ''],
[<a href={Google +'safesearch_help.html'}>Safe Search</a>,
PSafe, {active: 'active', moderate: 'moderate', off: 'off'}, 'moderate'],
[<>Result Size</>, PSize, {4: 'small', 8: 'large'}, 'small'],
].reduce(function(form, [name, pref, dict, defv]){
var li = <li/>, select = <select onchange={
'Application.prefs.setValue("'+ pref +'", this.value)'}/>;
defv = prefs.getValue(pref, defv);
for each(var [key, val] in Iterator(dict)){
var opt = <option value={val}>{key}</option>;
if(val === defv) opt.@selected = 'selected';
select.* += opt;
}
li.* += name + select;
form.ul.* += li;
return form;
}, <form>Options:<ul style="list-style:none"/></form>) +'',
execute: function(inp, mod){
Utils.openUrlInBrowser(Google +'search'+
Utils.paramsToString(params(inp, mod)));
},
preview: function(pbl, inp, mod, index){
var {q, hl, safe} = params(inp, mod), me = this,
$p = jQuery(pbl), $c = $p.find(ID);
if(!$c[0]) $c = $p.html(Base).find(ID).after(Logo +''), entry = '';
if(!q || entry === (entry = q + hl + safe + index)) return;
var rsz = prefs.getValue(PSize, 'small');
$c.addClass('loading');
CmdUtils.previewAjax(pbl, {
url: 'http://ajax.googleapis.com/ajax/services/search/web',
data: {v: '1.0', q: q, hl: hl, safe: safe,
rsz: rsz, start: index << (rsz === 'small' ? 2 : 3)},
dataType: 'json',
success: function({responseStatus: stat, responseData: data}){
if(stat !== 200) return oops(
$c, stat === 400 ? 'Out of page range.' : 'Error: '+ stat);
var {results, cursor} = data;
if(!results.length) return oops($c, 'No results.');
$c.removeClass().html(render(results, cursor));
$c.find('.b_open').each(function(i){
tie(this, function(){
this.disabled = true;
Utils.openUrlInBrowser(results[i].unescapedUrl);
})});
$c.find('.b_page').each(function(){
this.disabled || tie(this, function(){
me.preview(pbl, inp, mod, this.value - 1);
})});
},
error: function(x){ oops($c, x.status, x.statusText) },
});
var now = Date.now();
if(now - logot < 60 * 6e4) return;
logot = now;
jQuery.get(Google +'webhp', function(htm){
var [lg] = /<img [^>]+/(htm) || 0;
if(!lg) return;
Logo.img.@src = Google + (/\bsrc=\"?\/([^\"\s]+)/(lg) || 0)[1];
Logo.img.@height = (/\bheight=\D?(\d+)/(lg) || 0)[1];
});
},
previewDelay: 333,
author: 'satyr'.link('http://d.hatena.ne.jp/murky-satyr'), license: 'MIT',
});
function params({text}, mod)({
q: jQuery.trim(text), ie: 'utf-8',
hl: mod.in.data || prefs.getValue(PLang, ''),
cr: 'country'+ prefs.getValue(PFrom, ''),
safe: prefs.getValue(PSafe, ''),
});
function tie(it, fn){
it.addEventListener('focus', function(e){
this.blur();
fn.call(it);
e.preventDefault();
e.stopPropagation();
}, true);
}
function oops($c){
$c.removeClass('loading').addClass('error')
.text(Array.slice(arguments, 1).join(' '));
}
function render(res, cur){
var a2h, i2p, q2x, ggl = [
'<div class="count">',
cur.estimatedResultCount.link(cur.moreResultsUrl), '</div>',
paginates(cur.currentPageIndex + 1, cur.pages.length), '<ul>'];
for(var i in res) with(res[i]) ggl.push(
'<li><button class="b_open" accesskey="', a2h = 'ABCDEFGH'[i], '">', a2h,
'</button><a class="title" href="', unescapedUrl, '" accesskey="',
i2p = 'IJKLMNOP'[i] ,'">', title, '</a><kbd>', i2p,
'</kbd><span class="meta"><a href="', cacheUrl, '" accesskey="',
q2x = 'QRSTUVWX'[i], '">[cache]</a><kbd>', q2x, '</kbd> ', visibleUrl,
'</span><div class="content">', content, '</div></li>');
return ggl.join('') +'</ul>';
}
function paginates(cpi, len)(
'<div class="pagination">'+
btn('&lt;,', ',', cpi <= 1, cpi - 1) +
[btn(++i, i, cpi === i, i) for(i in Array(len)+0)].join('') +
btn('.&gt;', '.', cpi >= len, cpi + 1) +
'</div>');
function btn(txt, key, dis, val)(
'<button class="b_page" accesskey="'+ key +'" value="'+ val +
(dis ? '" disabled="disabled">' : '">') + txt +'</button>');
function gnoun(name, dict)({
_name: name, suggest: function(txt, htm, cb, sx){
if(sx || !txt) return [];
try { var re = RegExp(txt, 'i') } catch(_){ re = /(?:)/ }
return [{text: k, data: v, summary: v ? k +' ['+ v +']' : k }
for([k, v] in Iterator(dict)) if(re.test(k) || re.test(v))];
}});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment