diaspora/diaspora — Issue #2741: Improved bookmarklet link
Author: Yajo
Created: 2012-01-26 15:21:43+00:00
State: open

Hi, the bookmarklet in the right only extracts text, but I developed this one which formats it more accordingly to markdown. It displays images, bold, codeblocks, etc.

It's not minified, so you can read it better.

However, for it to work, first *bookmarklet.html.haml* must be fixed.

* Firebug reports a crash "Publisher is not defined" at line `Publisher.bookmarklet = true;`.
* Crashes if a `"` or `\n` character is passed in the *notes* GET param (they should be escaped for javascript to work).

No idea of how to fix that in ruby, but here is the javascript bookmarklet:

```
javascript:

/* All in a lambda to avoid polluting the current page */
(function(){
/* Get user's selection */
var sel = window.getSelection ? window.getSelection() :
document.getSelection ? document.getSelection() :
document.selection.createRange().text,
notes = '',

/* Make a paragraph a blockquote using Diaspora*'s Markdown */
blockquote = function(text) {
return text.trim().replace(/\n{2,}/g, '\n\n').replace(/^/gm, '>');
},

/* Remove newlines from given text */
removeNewLines = function(text) {
return text.replace(/\n/g, ' ');
},

/* Recursively extract selection text */
extract = function(node) {
var text = '',
/* Quit quotes from node's title (if it has one) */
title = (!node.title ? '' :
' "' + node.title.replace(/"/g, '"') + '"');

switch (node.nodeType) {

/* Avoid comment nodes */
case Node.COMMENT_NODE:
case Node.CDATA_SECTION_NODE:
return '';

/* When getting to a text node, don't recurse anymore */
case Node.TEXT_NODE:
if (!node.isElementContentWhitespace)
return node.textContent;

default:
/* Get node's text content recursively */
for (var n in node.childNodes) {
text += extract(node.childNodes[n]);
}

/* Special cases for some types of nodes */
switch (node.localName){
case 'img':
text = '\n\n!['
+ (removeNewLines(node.alt) || '')
+ ']('
+ removeNewLines(node.src)
+ removeNewLines(title)
+ ')\n\n';
break;

case 'a':
text = ' ['
+ removeNewLines(text)
+ ']('
+ removeNewLines(node.href)
+ removeNewLines(title)
+ ') ';
break;

case 'br':
text = '\n\n';
break;

case 'pre':
text = '```\n' + text.trim() + '\n```';
break;

case 'i':
case 'em':
text = '*' + text + '*';
break;

case 'b':
case 'strong':
text = '**' + text + '**';
break;

case 'blockquote':
text = blockquote(text) + '\n\n';
break;
}

/* Separate in paragraphs if the node is not inline */
try {
if (
window.getComputedStyle(node, null)
.getPropertyCSSValue('display').cssText
!= 'inline'
) {
text += '\n\n';
}
} finally{
return text;
}
}
};

/* Get selection's text */
for (var r = 0; r < sel.rangeCount; r++) {
notes += extract(sel.getRangeAt(r).cloneContents());
}

/* Add ">" at the beginning of each line to make it become a blockquote */
if (notes) notes = blockquote(notes);

/*console.log(notes); /* Uncomment to debug */

/* Generate URL */
var url = 'https://joindiaspora.com/bookmarklet?url='
+ encodeURIComponent(window.location.href)
+ '&title='
+ encodeURIComponent(document.title)
+ '¬es='
+ encodeURIComponent(notes)
+ '&v=1&noui=1&jump=';

/* Open the bookmarklet window */
if (!window.open(
url + 'doclose',
'diasporav1',
'location=yes,links=no,scrollbars=no,toolbar=no,width=620,height=250'
)) {
location.href = url + 'yes';
}

return undefined;
})();
```