Skip to content

Instantly share code, notes, and snippets.

@jlewin
Forked from johan/readme.md
Last active December 10, 2015 20:58
Show Gist options
  • Save jlewin/4491632 to your computer and use it in GitHub Desktop.
Save jlewin/4491632 to your computer and use it in GitHub Desktop.
**Fork Details** A quick and dirty update to refactor for the December 2012 site changes and well as account for the use of pjax, which happens to bypass userscript invocation for all urls except on page reloads. As such, a MutationObserver is registered to identify when pjax requests reload the #js-pjax-container and button injection logic is r…
// ==UserScript==
// @name (Re)fork any gist, including your own
// @namespace https://github.com/johan
// @description Adds a "fork" button to gists missing one at gist.github.com, so you can create multiple forks
// @match https://gist.github.com/*
// @include https://gist.github.com/*
// ==/UserScript==
var resourceUri;
// Only create the button on initial load and reuse on pjax reloads
var reforkListItem = (function () {
var li = document.createElement('li')
, a = document.createElement('a')
, sp = document.createElement('span');
a.className = 'minibutton fork-button'; // Apply button look and feel
a.title = 'Create another fork of this gist'; // Set hover text
// When clicked, append an http form for the uri/fork post and submit it
a.addEventListener('click', function () {
var f = document.body.appendChild(document.createElement('form'));
f.method = 'POST';
f.action = resourceUri + '/fork';
f.appendChild(document.querySelector('input[name=authenticity_token]'));
f.submit();
return false;
});
sp.className = 'mini-icon mini-icon-fork';; // Apply the fork icon
// Create the control tree
li.appendChild(a);
a.appendChild(sp);
a.appendChild(document.createTextNode('(Re)Fork'));
return li;
})();
// If missing and appropriate, add in the fork button
function injectForkButton() {
var pageActions = document.querySelector('.pagehead-actions');
var resourceLink = document.querySelector('input[name="link-field"]');
// Only attempt to inject when on an actual gist url (https://gist.github.com/\d+)
// and only when a '.pagehead-actions' element exists
// and only when the 'input[name="link-field"]' element exists
// and only when an existing '.fork-button' element is missing
if (/^\/\d+/.test(location.pathname) && pageActions && resourceLink && !document.querySelector('.fork-button')) {
resourceUri = resourceLink.getAttribute('value');
pageActions.appendChild(reforkListItem);
// Leave logging in for a while to confirm expected behavior
console.log('(Re)fork button injected');
}
}
// Initial page load injection
injectForkButton();
// Dynamic injection after pjax load and subsequent dom update of '#js-pjax-container'
//
// Observe 'childList' changes to '#js-pjax-container' and rerun injectForkButton
var target = document.querySelector('#js-pjax-container');
var JsMutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new JsMutationObserver(function (mutations) {
console.log('pjax-container mutation - checking for fork button');
injectForkButton();
});
observer.observe(target, { childList: true });
// TODO: Is it necessary to call observer.disconnect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment