Skip to content

Instantly share code, notes, and snippets.

@theY4Kman
Created July 23, 2014 18:23
Show Gist options
  • Select an option

  • Save theY4Kman/2d95080b392dba0780a5 to your computer and use it in GitHub Desktop.

Select an option

Save theY4Kman/2d95080b392dba0780a5 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Hive passwords utilities
// @description Highlights common passwords and copies to clipboard upon Reveal
// @match https://hive.hivelocity.net/admin/passwords/password/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @require http://github.com/bartaz/sandbox.js/raw/master/jquery.highlight.js
// @grant GM_setClipboard
// @copyright 2013, Zach "theY4Kman" Kanzler
// ==/UserScript==
$('input[type=password]').siblings('a').click(function() {
var $this = $(this);
var $input = $this.siblings('input');
if ($input.attr('type') == 'text') {
GM_setClipboard($input.val());
}
});
var IMPORTANT_ENTRIES_KEY = 'hive-important-entries';
var important_entries;
var unimportant_entries;
var important_entries_reverse = {};
var colors = ['#ff0037', '#00fff2', '#ffc300'];
function css_rgb_to_obj(css_rgb) {
var s_rgb = css_rgb.substr(4).slice(0, -1).split(', ');
return {r: parseInt(s_rgb[0]), g: parseInt(s_rgb[1]), b: parseInt(s_rgb[2])};
}
function rgb_obj_to_css(rgb) {
return 'rgb(' + [rgb.r, rgb.g, rgb.b].join(', ') + ')';
}
function get_readable_text_color(css_rgb) {
var rgb = css_rgb_to_obj(css_rgb);
var hsv = RGB2HSV(rgb);
hsv.hue = HueShift(hsv.hue, 180.0);
return rgb_obj_to_css(HSV2RGB(hsv));
}
function RGB2HSV(rgb) {
hsv = new Object();
max=max3(rgb.r,rgb.g,rgb.b);
dif=max-min3(rgb.r,rgb.g,rgb.b);
hsv.saturation=(max==0.0)?0:(100*dif/max);
if (hsv.saturation==0) hsv.hue=0;
else if (rgb.r==max) hsv.hue=60.0*(rgb.g-rgb.b)/dif;
else if (rgb.g==max) hsv.hue=120.0+60.0*(rgb.b-rgb.r)/dif;
else if (rgb.b==max) hsv.hue=240.0+60.0*(rgb.r-rgb.g)/dif;
if (hsv.hue<0.0) hsv.hue+=360.0;
hsv.value=Math.round(max*100/255);
hsv.hue=Math.round(hsv.hue);
hsv.saturation=Math.round(hsv.saturation);
return hsv;
}
// RGB2HSV and HSV2RGB are based on Color Match Remix [http://color.twysted.net/]
// which is based on or copied from ColorMatch 5K [http://colormatch.dk/]
function HSV2RGB(hsv) {
var rgb=new Object();
if (hsv.saturation==0) {
rgb.r=rgb.g=rgb.b=Math.round(hsv.value*2.55);
} else {
hsv.hue/=60;
hsv.saturation/=100;
hsv.value/=100;
i=Math.floor(hsv.hue);
f=hsv.hue-i;
p=hsv.value*(1-hsv.saturation);
q=hsv.value*(1-hsv.saturation*f);
t=hsv.value*(1-hsv.saturation*(1-f));
switch(i) {
case 0: rgb.r=hsv.value; rgb.g=t; rgb.b=p; break;
case 1: rgb.r=q; rgb.g=hsv.value; rgb.b=p; break;
case 2: rgb.r=p; rgb.g=hsv.value; rgb.b=t; break;
case 3: rgb.r=p; rgb.g=q; rgb.b=hsv.value; break;
case 4: rgb.r=t; rgb.g=p; rgb.b=hsv.value; break;
default: rgb.r=hsv.value; rgb.g=p; rgb.b=q;
}
rgb.r=Math.round(rgb.r*255);
rgb.g=Math.round(rgb.g*255);
rgb.b=Math.round(rgb.b*255);
}
return rgb;
}
function min3(a,b,c) {
return (a<b)?((a<c)?a:c):((b<c)?b:c);
}
function max3(a,b,c) {
return (a>b)?((a>c)?a:c):((b>c)?b:c);
}
function HueShift(h,s) {
h+=s; while (h>=360.0) h-=360.0;
while (h<0.0) h+=360.0;
return h;
}
function is_important_entry(id) {
return important_entries_reverse.hasOwnProperty(id);
}
function add_important_entry(id) {
if (is_important_entry(id))
return;
important_entries.push(id);
important_entries_reverse[id] = true;
unimportant_entries.splice(unimportant_entries.indexOf(id), 1);
save_important_entries();
}
function remove_important_entry(id) {
if (!is_important_entry(id))
return;
var index = important_entries.indexOf(id);
// This should not occur if is_important_entry(id) is false
// BUT I CHECK ANYWAY CUZ IM HARDCORE
if (index !== -1) {
important_entries.splice(index, 1);
delete important_entries_reverse[id];
unimportant_entries.push(id);
unimportant_entries.sort(function(a,b) { return a-b; });
save_important_entries();
}
}
function save_important_entries() {
window.localStorage[IMPORTANT_ENTRIES_KEY] = JSON.stringify(important_entries);
}
function load_important_entries() {
important_entries = _retrieve_important_entries() || [];
sync_reverse_important_entries();
}
function sync_reverse_important_entries() {
for (i=0; i<important_entries.length; i++)
important_entries_reverse[important_entries[i]] = true;
}
function _retrieve_important_entries() {
var saved = window.localStorage[IMPORTANT_ENTRIES_KEY];
if (saved)
return JSON.parse(saved);
}
Array.prototype.binaryClosest = function(searchElement) {
if (this.length == 0)
return undefined;
if (searchElement < this[0])
return null;
var minIndex = 0;
var maxIndex = this.length - 1;
var currentIndex;
var currentElement;
while (minIndex <= maxIndex) {
currentIndex = (minIndex + maxIndex) / 2 | 0;
currentElement = this[currentIndex];
if (currentElement < searchElement) {
minIndex = currentIndex + 1;
}
else if (currentElement > searchElement) {
maxIndex = currentIndex - 1;
if (minIndex > maxIndex) {
currentIndex--;
break;
}
} else {
return this[currentIndex];
}
}
return this[currentIndex];
}
$(function() {
var $result_list = $('#result_list');
var $tbody = $result_list.children('tbody');
// Build an array of the IDs on the page, which will later be binary searched
// to place an unstarred row back in its original position
unimportant_entries = $tbody.find('.action-select').map(function() { return parseInt($(this).val()); }).toArray();
function fix_striping() {
$tbody.children('.row1:visible, .row2:visible').removeClass('row1 row2').each(function(idx) {
this.setAttribute('class', 'row' + (idx % 2 + 1));
});
}
function highlight_important_entries() {
for (var i=0; i<important_entries.length; i++) {
var value = important_entries[i];
var $tr = $('.action-select[value="' + value + '"]').parents('tr');
if ($tr.length == 0)
continue;
$tr.addClass('important').removeClass('row1 row2');
$tr.prependTo($tbody);
var color = colors[i % colors.length];
// Get the RGB colour of the background, so we can set a readable text colour
var color_test = document.createElement('span')
color_test.style.color = color;
var rgb_bg = $(color_test).css('color');
var text_color = get_readable_text_color(rgb_bg);
// Don't know why .css('background', color) doesn't work
$tr[0].setAttribute('style', 'background: ' + color + '; color: ' + text_color + ';');
$tr.find(':not(input,select,option)').css('color', text_color);
}
}
function unhighlight_important_entry(id) {
var $tr = $('.action-select[value="' + id + '"]').parents('tr');
$tr.removeClass('important').addClass('row1');
$tr[0].setAttribute('style', null);
$tr.find(':not(input,select,option)').css('color', '');
$tr.remove();
// This all assumes no sorting of columns, so the sort is based on index. All I care about.
var closest_id = unimportant_entries.binaryClosest(id);
if (closest_id == null)
$tbody.children('tr:last-child').after($tr);
else
$('.action-select[value="' + closest_id + '"]').parents('tr').before($tr);
}
$tbody.on('change', '.star', function() {
var $this = $(this);
var id = parseInt($this.parents('tr').find('.action-select').val());
if ($this.prop('checked')) {
add_important_entry(id);
highlight_important_entries();
} else {
unhighlight_important_entry(id);
remove_important_entry(id);
}
fix_striping();
});
// Initialize important entries
load_important_entries();
// Remove from unimportant_entries
for (i=0; i<important_entries.length; i++)
unimportant_entries.splice(unimportant_entries.indexOf(important_entries[i]), 1);
unimportant_entries.sort(function(a,b) { return a-b; });
// Highlight them
highlight_important_entries();
// Then redo the row striping
fix_striping();
// Add column for starring rows (must be after load_important_entries, in order to pre-check starred boxes)
var $thead = $result_list.children('thead');
$thead.find('tr th:nth-child(1)').after($('<th><img src="https://i.imgur.com/EtaQ0pP.png" /></th>'));
$tbody.find('tr > td:nth-child(1)').each(function() {
var $this = $(this);
var td = document.createElement('td');
var checkbox = document.createElement('input');
checkbox.className = 'star';
checkbox.type = 'checkbox';
if (is_important_entry(parseInt($this.children('.action-select').val())))
checkbox.checked = 'checked';
td.appendChild(checkbox);
$this.after(td);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment