Skip to content

Instantly share code, notes, and snippets.

@potch
Last active December 23, 2015 05:58
Show Gist options
  • Save potch/6590249 to your computer and use it in GitHub Desktop.
Save potch/6590249 to your computer and use it in GitHub Desktop.
Code for Multi-file gist post.
// GistBin 1.0
// By Potch http://potch.me/
// Licensed under BSD.
(function() {
var thisTag = document.getElementsByTagName('script');
thisTag = thisTag[thisTag.length - 1];
var id = thisTag.getAttribute('data-id');
// We kind of need one of these.
if (!id) {
throw 'No Gist ID Specified!';
}
// Drop the standard Gist embed code in the page.
document.write('<script src="http://gist.github.com/' + id + '.js"></script>');
window.addEventListener('load', function() {
// Find the created gist DOM.
var binEl = document.getElementById('gist' + id);
if (!binEl) return;
binEl.classList.add('gistbin');
// Add in some custom styles.
binEl.innerHTML += '<style>\
.gistbin {\
position: relative;\
border: 1px solid #ddd;\
padding-top: 32px;\
overflow: hidden;\
border-radius: 3px;\
height: 400px;\
width: 640px;\
max-width: 100%;\
background: #f8f8ff;\
}\
.gistbin iframe, .gistbin.gist .gist-file {\
border-radius: 0;\
border: 0 none;\
position: absolute;\
height: 100%;\
top: 32px;\
left: 0;\
width: 100%;\
}\
.gistbin .file-data, \
.gistbin .lines {\
height: 100%;\
}\
.gistbin .lines tr {\
vertical-align: top;\
}\
.gistbin .gist-meta {\
position: absolute;\
bottom: 0;\
width: 100%;\
border-top: 1px solid #ddd;\
box-sizing: border-box;\
-moz-box-sizing: border-box;\
}\
.gistbin .gist-data {\
overflow: auto;\
}\
.gistbin .file-list {\
position: absolute;\
top: 0;\
width: 100%;\
height: 31px;\
background: #ececec;\
border-bottom: 1px solid #ddd;\
padding: 0 4px;\
font: 12px "Helvetica Neue",Helvetica,arial,freesans,clean,sans-serif;\
}\
.gistbin .file-list a {\
line-height: 26px;\
padding: 0 1em;\
color: #999;\
text-decoration: none;\
font-weight: bold;\
box-sizing: border-box;\
-moz-box-sizing: border-box;\
border: 1px solid transparent;\
height: 28px;\
display: inline-block;\
margin-top: 4px;\
position: relative;\
border-radius: 3px 3px 0 0;\
border-width: 1px 1px 0;\
}\
.gistbin .file-list .active {\
color: #666;\
border-color: #ddd #ddd transparent;\
background: #f8f8ff;\
}\
</style>';
// Create our top tab drawer.
var fileList = document.createElement('div');
fileList.className = 'file-list';
binEl.appendChild(fileList);
function arr(o) {
return Array.prototype.slice.call(o);
}
var currentPane;
var currentItem;
// Code for handling the changing of tabs.
function setVisible(file) {
var item = fileList.querySelector('[data-target="' + file + '"]');
var pane = binEl.querySelector('[data-file="' + file + '"]');
if (currentPane) currentPane.style.display = 'none';
if (currentItem) currentItem.classList.remove('active');
pane.style.display = 'block';
item.classList.add('active');
// Size the newly displayed pane to the parent, accounting for meta and nav.
pane.style.height = pane.parentNode.offsetHeight - 32 + 'px';
var gd = pane.querySelector('.gist-data');
if (gd) {
gd.style.height = pane.parentNode.offsetHeight - 67 + 'px';
}
currentPane = pane;
currentItem = item;
}
fileList.addEventListener('click', function(e) {
e.preventDefault();
var tgt = e.target.getAttribute('data-target');
if (tgt) {
setVisible(tgt);
}
})
// Find all the individual files from the embedded gist.
var fileTags = binEl.querySelectorAll('.gist-file');
var files = {};
arr(fileTags).forEach(function(f) {
var name = f.querySelector('.gist-meta a[href*="#file-"]');
var id = name.hash.substring(1);
name = name.textContent;
var lines = arr(f.querySelectorAll('.line-data .line'));
// extract the source from the embedded markup. Don't look at me.
lines = lines.map(function(l) {
return l.textContent;
});
files[name] = {
name: name,
src: lines.join('\n'),
embed: f,
id: id
};
// Create a tab for this file
var listItem = document.createElement('a');
listItem.href = '#';
listItem.setAttribute('data-target', id);
listItem.innerHTML = name;
fileList.appendChild(listItem);
f.setAttribute('data-file', id);
f.style.display = 'none';
});
// If the gist contains an 'index.html', we'll make an 'output' tab.
if ('index.html' in files) {
var iframe = document.createElement('iframe');
iframe.setAttribute('style', 'display: none;');
binEl.appendChild(iframe);
// Populate the iframe with index.
var doc = (iframe.contentWindow || iframe.contentDocument.parentWindow).document;
doc.open();
doc.write(files['index.html'].src);
doc.close();
iframe.onload = function() {
// Replace references to other files in the gist with
// inlined versions of said files.
for (var file in files) {
var link = doc.querySelector('link[href="' + file + '"]');
if (link) {
var styleTag = doc.createElement('style');
styleTag.textContent = files[file].src;
link.parentNode.insertBefore(styleTag, link);
link.parentNode.removeChild(link);
}
var script = doc.querySelector('script[src="' + file + '"]');
if (script) {
var scriptTag = doc.createElement('script');
scriptTag.textContent = files[file].src;
script.parentNode.insertBefore(scriptTag, script);
script.parentNode.removeChild(script);
}
}
// Add a tab for 'output'
var listItem = document.createElement('a');
listItem.href = '#';
iframe.setAttribute('data-file', '#output');
listItem.setAttribute('data-target', '#output');
listItem.innerHTML = 'output';
fileList.insertBefore(listItem, fileList.firstChild);
iframe.setAttribute('style', 'display: block;');
setVisible('#output');
};
}
});
})();
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>GistBin</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
GistBin Demo
<script src="gistbin.js" data-id="6575033"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment