Skip to content

Instantly share code, notes, and snippets.

@juliandescottes
Created December 2, 2014 22:19
Show Gist options
  • Save juliandescottes/1c12e1b7b06520a9135a to your computer and use it in GitHub Desktop.
Save juliandescottes/1c12e1b7b06520a9135a to your computer and use it in GitHub Desktop.
Spawn a tiny UI to create a bookmarklet. (see comment for the bookmark-ready javascript code)
(function () {
/**
* Adapted from http://ted.mielczarek.org/code/mozilla/bookmarklet.html
*/
//*****************************************************************************
// Do not remove this notice.
//
// Copyright 2001 by Mike Hall.
// See http://www.brainjar.com for terms of use.
//*****************************************************************************
var literalStrings; // For temporary storage of literal strings.
var iframe;
var crunch = function (f) {
try {
// Get input script code, process it and display output.
var input = "(function() {\n" + f.elements.codeIn.value + "\n})();";
var output = input;
output = replaceLiteralStrings(output);
output = removeComments(output);
output = compressWhiteSpace(output);
output = combineLiteralStrings(output);
output = restoreLiteralStrings(output);
// make the link
var link = iframe.contentWindow.document.getElementById('codeOut');
link.style.display = 'inline-block';
link.href = "javascript:" + output;
link.innerHTML = f.elements.bName.value || 'bookmarklet';
} catch (e) {
console.error(e);
} finally {
return false;
}
};
window._____crunch = crunch;
function replaceLiteralStrings(s) {
var i, c, t, lines, escaped, quoteChar, inQuote, literal;
literalStrings = new Array();
t = "";
// Split script into individual lines.
lines = s.split("\n");
for (i = 0; i < lines.length; i++) {
var j = 0;
inQuote = false;
while (j <= lines[i].length) {
c = lines[i].charAt(j);
// If not already in a string, look for the start of one.
if (!inQuote) {
if (c == '"' || c == "'") {
inQuote = true;
escaped = false;
quoteChar = c;
literal = c;
}
else
t += c;
}
// Already in a string, look for end and copy characters.
else {
if (c == quoteChar && !escaped) {
inQuote = false;
literal += quoteChar;
t += "__" + literalStrings.length + "__";
literalStrings[literalStrings.length] = literal;
}
else if (c == "\\" && !escaped)
escaped = true;
else
escaped = false;
literal += c;
}
j++;
}
t += "\n";
}
return t;
}
function removeComments(s) {
var lines, i, t;
// Remove '//' comments from each line.
lines = s.split("\n");
t = "";
for (i = 0; i < lines.length; i++)
t += lines[i].replace(/([^\x2f]*)\x2f\x2f.*$/, "$1");
// Replace newline characters with spaces.
t = t.replace(/(.*)\n(.*)/g, "$1 $2");
// Remove '/* ... */' comments.
lines = t.split("*/");
t = "";
for (i = 0; i < lines.length; i++)
t += lines[i].replace(/(.*)\x2f\x2a(.*)$/g, "$1 ");
return t;
}
function compressWhiteSpace(s) {
// Condense white space.
s = s.replace(/\s+/g, " ");
s = s.replace(/^\s(.*)/, "$1");
s = s.replace(/(.*)\s$/, "$1");
// Remove uneccessary white space around operators, braces and parentices.
s = s.replace(/\s([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])/g, "$1");
s = s.replace(/([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])\s/g, "$1");
return s;
}
function combineLiteralStrings(s) {
var i;
s = s.replace(/"\+"/g, "");
s = s.replace(/'\+'/g, "");
return s;
}
function restoreLiteralStrings(s) {
var i;
for (i = 0; i < literalStrings.length; i++)
s = s.replace(new RegExp("__" + i + "__"), literalStrings[i]);
return s;
}
function init () {
var containerId = '___bookmarklet-cruncher-container';
// remove previous container if needed
if (document.getElementById(containerId)) {
var el = document.getElementById(containerId);
el.parentNode.removeChild(el);
}
// styles
var containerStyle = [
'position:fixed',
'z-index:10000',
'background:white',
'border:1px solid #666',
'top:50%', 'left:50%',
'width:700px', 'height:250px',
'margin:-125px 0 0 -300px',
'box-sizing:border-box',
'box-shadow:0 0 10px rgba(0,0,0,0.5)'
].join(';');
var linkStyle = [
'display:none',
'font-family:Arial',
'font-size:12px',
'padding:3px 10px',
'background:#D0E3FF',
'font-weight: bold',
'color:#1767D2',
'border:1px solid #1767D2'
].join(';');
var container = document.createElement('DIV');
container.id = containerId;
container.style.cssText = containerStyle;
iframe = document.createElement('IFRAME');
iframe.style.width = '698px';
iframe.style.height = '248px';
iframe.style.borderWidth = '0';
container.appendChild(iframe);
iframe.onload = function () {
console.log('Bookmarklet cruncher : iframe loaded');
iframe.onload = function () {};
var doc = iframe.contentWindow.document;
doc.open();
doc.write('<form style="margin:0;" action="GET" id="crunchForm">' +
'<div style="margin:10px 0;">' +
' <input name="bName" type="text" placeholder="your bookmarklet name ..." style="font-family:Courier; width:100%; box-sizing:border-box;"/>' +
'</div>' +
'<div style="margin:10px 0;">' +
' <textarea name="codeIn" rows="10" cols="80" placeholder="your script goes here ..." style="font-family:Courier; width: 100%; height:160px; box-sizing:border-box;"></textarea>' +
'</div>' +
'<div style="margin:10px 0;">' +
' <input class="button" type="submit" value="Create bookmarklet" />' +
' <a id="codeOut" href="#" style="' + linkStyle +'">Your Bookmarklet</a>' +
' <button style="float:right; color:red;" class="button" id="quit-button">Quit</button>' +
'</div>' +
'</form>');
doc.close();
var crunchForm = iframe.contentWindow.document.getElementById('crunchForm');
crunchForm.addEventListener('submit', function (e) {
e.stopPropagation();
e.preventDefault();
crunch(crunchForm);
});
var quitButton = iframe.contentWindow.document.getElementById('quit-button');
quitButton.addEventListener('click', function (e) {
document.body.removeChild(container);
});
};
document.body.appendChild(container);
}
init();
})();
@juliandescottes
Copy link
Author

And here it is, after auto-bookmarkletisation :

javascript:(function(){(function(){var literalStrings;var iframe;var crunch=function(f){try{var input="(function() {\n"+f.elements.codeIn.value+"\n})();";var output=input;output=replaceLiteralStrings(output);output=removeComments(output);output=compressWhiteSpace(output);output=combineLiteralStrings(output);output=restoreLiteralStrings(output);var link=iframe.contentWindow.document.getElementById('codeOut');link.style.display='inline-block';link.href="javascript:"+output;link.innerHTML=f.elements.bName.value||'bookmarklet';}catch(e){console.error(e);}finally{return false;}};window._____crunch=crunch;function replaceLiteralStrings(s){var i,c,t,lines,escaped,quoteChar,inQuote,literal;literalStrings=new Array();t="";lines=s.split("\n");for(i=0;i<lines.length;i++){var j=0;inQuote=false;while(j<=lines[i].length){c=lines[i].charAt(j);if(!inQuote){if(c=='"'||c=="'"){inQuote=true;escaped=false;quoteChar=c;literal=c;}else t+=c;}else{if(c==quoteChar&&!escaped){inQuote=false;literal+=quoteChar;t+="__"+literalStrings.length+"__";literalStrings[literalStrings.length]=literal;}else if(c=="\\"&&!escaped)escaped=true;else escaped=false;literal+=c;}j++;}t+="\n";}return t;}function removeComments(s){var lines,i,t;lines=s.split("\n");t="";for(i=0;i<lines.length;i++)t+=lines[i].replace(/([^\x2f]*)\x2f\x2f.*$/,"$1");t=t.replace(/(.*)\n(.*)/g,"$1 $2");lines=t.split("*/");t="";for(i=0;i<lines.length;i++)t+=lines[i].replace(/(.*)\x2f\x2a(.*)$/g,"$1 ");return t;}function compressWhiteSpace(s){s=s.replace(/\s+/g," ");s=s.replace(/^\s(.*)/,"$1");s=s.replace(/(.*)\s$/,"$1");s=s.replace(/\s([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])/g,"$1");s=s.replace(/([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])\s/g,"$1");return s;}function combineLiteralStrings(s){var i;s=s.replace(/"\+"/g,"");s=s.replace(/'\+'/g,"");return s;}function restoreLiteralStrings(s){var i;for(i=0;i<literalStrings.length;i++)s=s.replace(new RegExp("__"+i+"__"),literalStrings[i]);return s;}function init(){var containerId='___bookmarklet-cruncher-container';if(document.getElementById(containerId)){var el=document.getElementById(containerId);el.parentNode.removeChild(el);}var containerStyle=['position:fixed','z-index:10000','background:white','border:1px solid #666','top:50%','left:50%','width:700px','height:250px','margin:-125px 0 0 -300px','box-sizing:border-box','box-shadow:0 0 10px rgba(0,0,0,0.5)'].join(';');var linkStyle=['display:none','font-family:Arial','font-size:12px','padding:3px 10px','background:#D0E3FF','font-weight: bold','color:#1767D2','border:1px solid #1767D2'].join(';');var container=document.createElement('DIV');container.id=containerId;container.style.cssText=containerStyle;iframe=document.createElement('IFRAME');iframe.style.width='698px';iframe.style.height='248px';iframe.style.borderWidth='0';container.appendChild(iframe);iframe.onload=function(){console.log('Bookmarklet cruncher : iframe loaded');iframe.onload=function(){};var doc=iframe.contentWindow.document;doc.open();doc.write('<form style="margin:0;" action="GET" id="crunchForm">'+'<div style="margin:10px 0;">'+'  <input name="bName" type="text" placeholder="your bookmarklet name ..." style="font-family:Courier; width:100%; box-sizing:border-box;"/>'+'</div>'+'<div style="margin:10px 0;">'+'  <textarea name="codeIn" rows="10" cols="80" placeholder="your script goes here ..." style="font-family:Courier; width: 100%; height:160px; box-sizing:border-box;"></textarea>'+'</div>'+'<div style="margin:10px 0;">'+'  <input class="button" type="submit" value="Create bookmarklet" />'+'  <a id="codeOut" href="#" style="'+linkStyle+'">Your Bookmarklet</a>'+'  <button style="float:right; color:red;" class="button" id="quit-button">Quit</button>'+'</div>'+'</form>');doc.close();var crunchForm=iframe.contentWindow.document.getElementById('crunchForm');crunchForm.addEventListener('submit',function(e){e.stopPropagation();e.preventDefault();crunch(crunchForm);});var quitButton=iframe.contentWindow.document.getElementById('quit-button');quitButton.addEventListener('click',function(e){document.body.removeChild(container);});};document.body.appendChild(container);}init();})();})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment