<html>
<head>
<meta charset=utf-8 />
<title>PAEz JS Bin Bookmarkleter</title>
<script src="https://dl.dropboxusercontent.com/u/3610419/WebPages/JS/uglify.js"></script>
</head>
<body style="display:none">
<a id="bookmarklet" href="a">Indent Lines for Code</a>
<script id='code' type='text/bookmarklet'>
%code%
</script>
<script>
window.addEventListener('load', function() {
document.body.style.display = "block";
// Im using Uglify to help make the bookmarklet because all of the js
// I tried that was meant to do it would keep failing (especially on comments)
// Uglify hasnt failed yet and you get the bonus of its cool compressor stuff
// ...Thanks, https://github.com/johnkpaul/bookmarkletify/blob/master/bookmarkletify.js
var code = document.querySelector('#code').innerText;
//code = code.replace('window.runnerWindow.proxyConsole','console');
var bookmarklet = document.querySelector('#bookmarklet');
var ast = UglifyJS.parse(code);
ast.figure_out_scope();
var compressor = UglifyJS.Compressor({
sequences: true, // join consecutive statemets with the “comma operator”
properties: true, // optimize property access: a["foo"] → a.foo
dead_code: true, // discard unreachable code
drop_debugger: true, // discard “debugger” statements
unsafe: false, // some unsafe optimizations (see below)
conditionals: true, // optimize if-s and conditional expressions
comparisons: true, // optimize comparisons
evaluate: true, // evaluate constant expressions
booleans: true, // optimize boolean expressions
loops: true, // optimize loops
unused: true, // drop unused variables/functions
hoist_funs: true, // hoist function declarations
hoist_vars: false, // hoist variable declarations
if_return: true, // optimize if-s followed by return/continue
join_vars: true, // join var declarations
cascade: true, // try to cascade `right` into `left` in sequences
side_effects: true, // drop side-effect-free statements
warnings: true, // warn about potentially dangerous optimizations/code
global_defs: {} // global definitions
});
ast = ast.transform(compressor);
code = ast.print_to_string();
bookmarklet.setAttribute('href', 'javascript:(function(){;' + encodeURI(code) + ';})()');
})
</script>
</body>
</html>
//noprotect
function findFocused (){
var found = false;
var focusEl = window.top.document;
var failSafe = 0;
var parent = window;
while (false === found) {
// has an active element so need to keep searching, ie in a frame
if (focusEl.activeElement) {
// set next focusEl
focusEl = focusEl.activeElement;
if (focusEl instanceof HTMLIFrameElement) {
parent = focusEl.contentDocument;
focusEl = focusEl.contentDocument;
}
// found iframe in design mode
if (focusEl.designMode == 'on' || focusEl.contentEditable) {
// no need to carry on
found = true;
}
}
// no more active elements so we can stop
else {
found = true;
}
failSafe++;
// failsafe in case something went wrong to prevent infinite loop
if (failSafe > 100) {
found = true;
alert('Sorry, couldn\'t find target to insert text into.');
return false;
}
}
if (found) return focusEl;
else return false;
}
function pasteText (focusEl, text, html) {
if (focusEl.designMode == 'on') {
//console.log('designmode');
if (!html) {
// replace line breaks with <br/> tags
text = text.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br/>$2');
}
// insert
focusEl.execCommand('insertHtml', false, text);
}
// input, textarea
else if (
focusEl.tagName.toLowerCase() == 'input'
|| focusEl.tagName.toLowerCase() == 'textarea'
)
{
//console.log('input');
// get start and end position of caret
var startPos = focusEl.selectionStart;
var endPos = focusEl.selectionEnd;
// insert text
focusEl.value = focusEl.value.substring(0, startPos)
+ text
+ focusEl.value.substring(endPos, focusEl.value.length);
// update caret position
focusEl.setSelectionRange(startPos + text.length, startPos + text.length);
}
// if content editable
else if (focusEl.contentEditable) {
//console.log('contentEditable');
// get selection
var selection = parent.getSelection();
var range = selection.getRangeAt(0);
range.deleteContents();
// get text
if (html) {
var div = document.createElement('div');
div.innerHTML = text;
range.insertNode(div);
}
else {
var text = text.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br/>$2');
var texts = text.split('<br/>');
// insert
for (var i=texts.length-1; i>=0; i--) {
range.insertNode(document.createTextNode(texts[i]));
if (i > 0) {
range.insertNode(document.createElement('br'));
}
}
}
range.collapse(true);
range.detach();
}
}
function getSelected(focusEl){
var startPos = focusEl.selectionStart;
var endPos = focusEl.selectionEnd;
return focusEl.value.substring(startPos, endPos);
}
var el = findFocused();
var text = getSelected(el);
if (text.length>0){
var lines = text.split('\n');
for (var i=0, end=lines.length;i<end;i++) {
lines[i]=' '+lines[i];
}
text=lines.join('\n');
pasteText(el, text);
}
Output
300px
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |