Last active
April 5, 2018 15:16
-
-
Save paulroub/d633a8a8eb31f9123242 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Open Multiple Question Links | |
// @namespace http://roub.net/ | |
// @version 0.9.3 | |
// @description open multiple selected unique question links, skipping non-questions | |
// @author Paul Roub | |
// @contributor Mogsdad | |
// @include *://chat.stackoverflow.com/rooms/41570/so-close-vote-reviewers | |
// @include *://chat.stackoverflow.com/search* | |
// @grant GM_openInTab | |
// ==/UserScript== | |
// tested on: | |
// Chrome 45.0.2454.101 w/TamperMonkey 3.11 | |
// Firefox 41.0 w/GreaseMonkey 3.4.1 | |
document.addEventListener("selectionchange", catchSelectionChange); | |
let picker = null, | |
pickerChild = null, | |
pickerLink = null, | |
ls = [], | |
pending = false; | |
function catchSelectionChange() { | |
if (pending) { | |
return; | |
} | |
pending = true; | |
// debounce a bit | |
setTimeout(function() { | |
pending = false; | |
const selection = window.getSelection(); | |
if (selectionIsEmpty(selection)) { | |
hidePicker(); | |
} else { | |
showPicker(selection); | |
} | |
}, 50); | |
} | |
function selectionIsEmpty(sel) { | |
return (!sel) || (sel.rangeCount < 1); | |
} | |
function hidePicker() { | |
if (picker) { | |
picker.style.display = 'none'; | |
} | |
} | |
function showPicker(selection) { | |
if (!picker) { | |
picker = document.createElement('div'); | |
picker.style.position = 'fixed'; | |
picker.style.top = 0; | |
picker.style.right = 0; | |
picker.style.backgroundColor = '#FFF'; | |
picker.style.color = '#000'; | |
picker.style.border = '1px solid #666'; | |
picker.style.zIndex = 1000; | |
picker.style.cursor = 'pointer'; | |
picker.style.padding = '.5em'; | |
document.body.appendChild(picker); | |
pickerLink = document.createElement('a'); | |
picker.appendChild(pickerLink); | |
pickerLink.addEventListener('mousedown', function(e) { | |
openLinks(ls); | |
e.stopPropagation(); | |
e.preventDefault(); | |
return false; | |
}); | |
pickerChild = document.createElement('div'); | |
pickerChild.style.display = 'none'; | |
picker.appendChild(pickerChild); | |
} | |
const r = selection.getRangeAt(0); | |
pickerChild.innerHTML = ''; | |
pickerChild.appendChild(r.cloneContents()); | |
ls = getQLinks(r); | |
if (ls.length > 0) { | |
pickerLink.innerHTML = '[' + ls.length + ']'; | |
const qtitle = (ls.length > 1) ? ' selected questions' : ' selected question'; | |
pickerLink.title = 'Open ' + ls.length + qtitle + ' in tabs'; | |
picker.style.display = 'block'; | |
} else { | |
hidePicker(); | |
} | |
} | |
function getQLinks(range) { | |
var container = range.commonAncestorContainer; | |
if ((! container) || (! container.getElementsByTagName)) | |
return []; | |
var as = container.getElementsByTagName('a'); | |
var unique = []; | |
qs = Array.prototype.slice.call(as).filter(function(el) { | |
var postRe = /stackoverflow\.com\/[aq](uestions)?\/\d/; | |
if (range.intersectsNode(el) && el.offsetParent && el.href.match(postRe)) { | |
var id = el.href.match(/\d+/)[0]; | |
if (unique.indexOf(id) == -1) { | |
unique.push(id); | |
return true; | |
} | |
} | |
return false; | |
}); | |
return qs; | |
} | |
function openLink(q) { | |
if ((typeof(GM) != 'undefined') && GM.openInTab) { | |
GM.openInTab(q.href, true); | |
} else if (typeof(GM_openInTab) != 'undefined') { | |
GM_openInTab(q.href, true); | |
} | |
} | |
function openLinks(qs) { | |
console.log(qs); | |
if (qs.length) { | |
qs.forEach( | |
function(q) { | |
openLink(q); | |
} | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment