Skip to content

Instantly share code, notes, and snippets.

@satyr
Last active October 6, 2016 04:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save satyr/99201 to your computer and use it in GitHub Desktop.
Save satyr/99201 to your computer and use it in GitHub Desktop.
Builds a text (from the page title etc.) and sends it to your clipboard.
const
H = Utils.escapeHtml,
Aliases = {
t: {
help: 'title',
get text(){ return info().title },
},
u: {
help: 'URL',
get text(){ return info().url },
},
a: {
help: 'title and URL as link tag',
get text(){
var _ = info()
return '<a href="'+ H(_.url) +'">'+ H(_.title) +'</a>'
},
},
f: {
help: 'favicon URL',
get text(){
var doc = CmdUtils.getDocument()
var lnk = doc.querySelector('link[rel~=icon]')
return lnk ? lnk.href : 'http://'+ doc.location.hostname +'/favicon.ico'
},
},
F: {
help: 'favicon as data:image/png',
get text(){ return src2du(favicon()) },
},
c: {
help: 'clipboard',
get text(){ return Utils.clipboard.text },
},
s: {
help: 'selected text',
get text(){ return CmdUtils.getSelection() },
},
h: {
help: 'selection as HTML',
get text(){ return CmdUtils.getHtmlSelection() },
},
q: {
help: 'selection as blockquote',
get text(){
var _ = info()
return '<blockquote cite="'+ H(_.url) +'" title="'+ H(_.title) +'">'+
CmdUtils.getHtmlSelection() +'</blockquote>'
}
},
i: {
help: 'selected image (or "1x1 transparent" if none) as data:image/png',
get text(){
let img = imgnow()
return img
? img2du(img)
: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCA'+
'QAAAC1HAwCAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII'
}
},
j: {
help: 'snapshot of focused window as data:image/jpeg',
get text(){ return snapshot('jpeg') },
},
p: {
help: 'snapshot of focused window as data:image/png',
get text(){ return snapshot('png') },
},
M: {
help: 'selection as MD5 hash',
get text(){
return Utils.computeCryptoHash('MD5', CmdUtils.getSelection())
},
},
S: {
help: 'selection as SHA1 hash',
get text(){
return Utils.computeCryptoHash('SHA1', CmdUtils.getSelection())
},
},
d: {
help: 'current datetime in RFC3399 format',
get text(){ return new Date().toISOString() },
},
U: {
help: 'URL as JSON',
get text(){
var o = info(), a = context.focusedWindow.document.createElement('a')
a.href = o.url
for(let p of ['protocol', 'host', 'pathname', 'search', 'hash'])
o[p] = a[p]
o.query = o.search ? Utils.urlToParams(o.search) : {}
return JSON.stringify(o, null, 2)
},
},
n: {
help: 'line feed character',
text: Utils.OS === 'WINNT' ? '\r\n' : '\n',
},
T: {
help: 'tab character',
text: '\t',
},
/*
_: {
help: '',
get text(){},
},
*/
},
REA = RegExp('['+ Object.keys(Aliases).join('') +']', 'g'),
AliasHelp =
'<ul style="list-style:none; margin:0.4ex 0.2em; padding:0">[ Aliases ]'+
[for(k of Object.keys(Aliases))
'<li><tt><b>'+ k +'</b>:</tt>'+ H(Aliases[k].help) +'</li>'
].join('') + '</ul>',
Listers = {
'a@href': {
help: H('<a href="...">') +' in page',
text: a => a.href,
html: a => ax(a.href, a.textContent),
*[Symbol.iterator](){ yield* uni(qsa('a[href], area[href]'), 'href') },
},
'link@href': {
help: H('<link href="...">') +' in page',
text: l => l.href,
html: function(l){
let t = l.rel || l.type
return '['+ (/\b(?:rss|atom|xml|icon)\b/i.exec(t) || t) +'] '+
ax(l.href, l.title)
},
*[Symbol.iterator](){ yield* uni(qsa('link[href]'), 'href') },
},
'img@src': {
help: H('<img src="...">') +' in page',
text: i => i.src,
html: i => '<img src="'+ H(i.src) +'" style="max-width:90%"/>',
*[Symbol.iterator](){ yield* uni(qsa(ImgQ), 'src') },
},
'embed@src': {
help: H('<embed src="...">') +' in page',
text: e => e.src,
html: e =>
'<embed src="'+ H(t) +'" height="200" wmode="opaque"/>',
*[Symbol.iterator](){ yield* uni(qsa('embed[src]'), 'src') },
css: 'embed {vertical-align:top} li {height:200px}',
},
tabs: {
help: 'tab title/URL',
text: d => d.title +'\n'+ d.location.href,
html: d => ax(d.location.href, d.title),
*[Symbol.iterator](){ for(let t of Utils.tabs) yield t.document },
},
/*
_: {
help: '',
text: function() ,
html: function() ,
*[Symbol.iterator](){},
},
*/
},
ListerSuggs = Object.keys(Listers).map((k, i) => ({
text: k, data: Listers[k], summary: k, index: i
})),
Images = {
selected: imgnow,
favicon: favicon,
snapshot: () => snapshot('png'),
},
ImgQ = 'img, input[type=image]',
DUCache = {'': 'data:,...'};
[{
name: 'copy',
argument: {
name: 'copy format',
label: 'format',
rankLast: true,
default: function nt_copy_default(){
return this._sugg(Bin.lastInput() || '')
},
suggest: function nt_copy_suggest(txt, htm, cb, sx){
return txt && !sx ? [this._sugg(Bin.lastInput(txt))] : []
},
_sugg: function(t){
return {text: t, summary: t.replace(REA, this._mark)}
},
_mark: $ => '<u>'+ H($) +'</u>',
},
description:
'Collects various informations into a text and sends it to clipboard, ' +
'using single character aliases.',
help:
'Try: <ul><li>'+
'"copy tnu" to copy the page title and url separated by a newline'+
'</li><li>'+
'"copy cs" to append the selection to clipboard'+
'</li></ul>etc.'+
AliasHelp,
execute: function copy_execute({object: {text}}){
copy1(parse(text), this);
},
preview: function copy_preview(pb, {object: {text}}){
pb.innerHTML =
'<pre>'+ (H(parse(text)) || '<em>empty</em>') +'</pre>' + AliasHelp
},
previewDelay: 200,
}, {
name: 'copy all',
arguments: {
object: {
name: 'copy list',
label: '...',
default: function nt_ca_default(){
return ListerSuggs[Bin.lastSelection()]
},
suggest: function nt_ca_suggest(txt, htm, cb, sx){
if(!txt || (sx || 0)[1]) return [];
var ss = CmdUtils.grepSuggs(txt, ListerSuggs);
if(ss.length) Bin.lastSelection(ss[0].index);
return ss;
},
},
modifier_filter: noun_arb_text,
},
description:
'Copies a newline separated list of all ... to clipboard.',
help: '<dl>'+
[for (k of Object.keys(Listers))
'<dt><b><code>'+ k +'</code></b></dt><dd>'+ H(Listers[k].help) +'</dd>'
].join('') +'</dl>',
execute: function copyall_execute(
{object: {text: what, data: lister}, modifier: {text: filter}}){
if(!lister) return;
var list = pick(lister, filter);
if(!list.length) return;
var r = list.map(lister.text).join('\n');
CmdUtils.copyToClipboard(r);
displayMessage(
what +' x '+ list.length + ' ('+ r.length.toLocaleString() +' chars)',
this);
},
preview: function copyall_preview(
pb, {object: {data: lister}, modifier: {text: filter}}){
if(!lister) return void this.previewDefault(pb)
var list = pick(lister, filter)
if(!list.length) return void(pb.innerHTML = '<code><b>[]</b></code>')
var me = this
CmdUtils.previewList(
pb, list.map(lister.html),
function copyall_one(i){ copy1(lister.text(list[i]), me) },
this._css + (lister.css || ""))
},
previewDelay: 250,
_css: '.uri {display:block; font-size:88%}',
}, {
name: 'copy image',
description: 'Copies an image as bitmap.',
help: 'Targets:'+
[for(k of Object.keys(Images)) ' <code><b>'+ k +'</b></code>'],
argument: CmdUtils.NounType('target', Images),
execute: function copyimg_execute(args){
var [src, img] = this._get(args);
if(!src) return;
Utils.clipboard.image = img;
displayMessage({text: src}, this);
},
preview: function copyimg_preview(pb, args){
var [src] = this._get(args);
if(!src) return void this.previewDefault(pb);
var hs = H(src)
pb.innerHTML =
'<img src="'+ hs +'"><br><code><a href="'+ hs +'">'+ hs
},
_get: function copyimg_get({object: {data}}){
var img = data ? data() : imgnow() || favicon();
return [img && (img.src || img), img];
},
}].forEach(function CopyCommand(o){
o.icon = 'chrome://ubiquity/skin/icons/convert.png';
CmdUtils.CreateCommand(o);
});
function copy1(txt, me){
txt && displayMessage({
text: Utils.clipboard.text = txt,
onclick: /^[a-z]+:./.test(txt) && (() => Utils.openUrlInBrowser(txt)),
}, me);
}
function snapshot(type){
var win = context.focusedWindow;
return CmdUtils.getWindowSnapshot(win, {type: type, width: win.innerWidth});
}
function imgnow(){
var {document} = CmdUtils;
return (
/^image\/./.test(document.contentType)
? document.body.firstChild
: (CmdUtils.getSelectedNodes(ImgQ)[0] ||
context.focusedWindow.document.querySelector(ImgQ)));
}
function src2du(src, ph){
return DUCache[src] ||
(CmdUtils.getImageSnapshot(src, function(du){ DUCache[src] = du }),
DUCache[src] = ph || DUCache[''])
}
function img2du(img){
var u = DUCache[img.src]
if(u) return u
var canvas = $('<canvas>', {width: img.width, height: img.height})[0]
canvas.getContext('2d').drawImage(img, 0, 0)
return DUCache[img.src] = canvas.toDataURL()
}
function info(){
var doc = CmdUtils.document, {URL: u, title: t} = doc
, a = u.startsWith('https://inoreader.com/') &&
doc.querySelector('.article_current .article_title_link')
if(a){
u = a.href
t = a.textContent.trim()
}
return {url: u, title: t}
}
function parse(txt){ return txt.replace(REA, replr) }
function replr(m){ return Aliases[m].text }
function wins(){
let w = CmdUtils.window
return [w].concat(Array.slice(w))
}
function qsa(q){
return Array.concat.apply(
0, [for(w of wins()) Array.slice(w.document.querySelectorAll(q))])
}
function uni(a, key){
var d = {__proto__: null};
for(let x of a) d[x[key]] = x;
return Object.values(d)
}
function pick(lister, filter){
if(filter){
let re = Utils.regexp(filter, 'i')
return [for(x of lister) if(re.test(lister.text(x))) x]
}
return [...lister]
}
function ax(href, text){
var a = H(text || href).link(H(href))
return text ? a + '<code class="uri">'+ H(href) +'</code>' : a
}
function favicon(){
return Utils.currentChromeWindow.gBrowser.selectedTab.image
}
$.extend(feed, {author: 'satyr', license: 'X'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment