Skip to content

Instantly share code, notes, and snippets.

@paulroub
Last active April 5, 2018 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save paulroub/d633a8a8eb31f9123242 to your computer and use it in GitHub Desktop.
Save paulroub/d633a8a8eb31f9123242 to your computer and use it in GitHub Desktop.
// ==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