Last active
May 12, 2016 13:18
-
-
Save keithshep/6b96889c60bd86b23433 to your computer and use it in GitHub Desktop.
Some JavaScript Cheats
This file contains 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
// forward slashes don't work well in URI components even when encoded as %2F. Many server side implementations | |
// still stumble on them. We can encode/decode the string with a simple scheme like: | |
// 'hi / there / \\ dude / \\f\\b\\\\'.replace(/\\/g, '\\b').replace(/\//g, '\\f').replace(/\\f/g, '/').replace(/\\b/g, '\\'); | |
function encURIComp(str) { | |
return encodeURIComponent(str.replace(/\\/g, '\\b').replace(/\//g, '\\f')); | |
} | |
function decURIComp(str) { | |
return decodeURIComponent(str).replace(/\\f/g, '/').replace(/\\b/g, '\\'); | |
} | |
function compareBasic(x, y) { | |
if(x < y) { | |
return -1; | |
} else if(x > y) { | |
return 1; | |
} else { | |
return 0; | |
} | |
} | |
/** | |
* This function simply returns (x - y) and thus is a suitable comparison function | |
* to use for sorting or searching numeric values | |
* @param x {number} | |
* @param y {number} | |
* @return {number} | |
*/ | |
function compareNumeric(x, y) { | |
return x - y; | |
} | |
function compareGenomic(x, y) { | |
var chrCmp = compareBasic(x.chr, y.chr); | |
if(chrCmp != 0) { | |
return chrCmp; | |
} else { | |
return x.pos - y.pos; | |
} | |
} | |
/** | |
* Binary search which returns the matchin index -(insertIndex + 1) in the case that no match is found | |
* @param array a sorted sorted array | |
* @param x the value we're searching for | |
* @param [compFunc=compareNumeric] the function used to compare values for the binary search. This | |
* function takes two parameters (x, y) and will return a number less than, greater than or equal | |
* to zero depending on whether x is less than, greater than or equal to y respectively | |
* @return {number} the index | |
*/ | |
function binarySearch(array, x, compFunc) { | |
if(typeof compFunc === 'undefined') { | |
compFunc = compareNumeric; | |
} | |
var low = 0; | |
var high = array.length - 1; | |
while (low <= high) { | |
var mid = (low + high) >> 1; | |
var midVal = array[mid]; | |
var compVal = compFunc(midVal, x); | |
if(compVal < 0) { | |
low = mid + 1; | |
} else if(compVal > 0) { | |
high = mid - 1; | |
} else { | |
return mid; | |
} | |
} | |
return -(low + 1); | |
} | |
function parseInterval(intervalStr) { | |
var match = intervalStr.match(/^\s*(Chr)?([a-z0-9]+)\s*:\s*([0-9]+)\s*-\s*([0-9]+)\s*$/i); | |
if(match) { | |
var interval = { | |
chr: match[2], | |
startPos: parseInt(match[3]), | |
endPos: parseInt(match[4]), | |
}; | |
interval.size = interval.endPos - interval.startPos + 1; | |
return interval; | |
} else { | |
return null; | |
} | |
} | |
/** | |
* a class to simplify working with bootstrap dropdowns. For this to work all of the clickable | |
* 'a' element must have a 'data-value' attribute. These values must correspond to the string | |
* values used in the value getter/setter function. Any item under dropdownDiv with an | |
* data-dropdown-label will have its text set to match the text of the selected 'a' | |
* @param dropdownDiv | |
* the 'div' containing the 'button' and 'ul' elements for the dropdown. | |
* @constructor | |
*/ | |
function BootstrapDropdown(dropdownDiv) { | |
var self = this; | |
var value = null; | |
var opts = dropdownDiv.find('a[data-value]'); | |
var ddLbls = dropdownDiv.find('[data-dropdown-label]') | |
this.getValue = function() { | |
return value; | |
}; | |
this.setValue = function(val) { | |
value = val; | |
if(val !== null) { | |
ddLbls.text(dropdownDiv.find('a[data-value="' + val + '"]').text()); | |
} | |
}; | |
this.onChange = null; | |
opts.click(function(e) { | |
e.preventDefault(); | |
var newVal = $(this).attr('data-value'); | |
self.setValue(newVal); | |
if(self.onChange) { | |
self.onChange(); | |
} | |
}); | |
self.setValue(opts.first().attr('data-value')); | |
} | |
/** | |
* A small wrapper around setTimeout that allows for preemption. | |
* @constructor | |
*/ | |
function DelayedPreemptable() { | |
var timeoutID = null; | |
this.delay = function(func, delayMillisecs) { | |
if(timeoutID !== null) { | |
window.clearTimeout(timeoutID); | |
timeoutID = null; | |
} | |
if(typeof delayMillisecs === 'undefined' || delayMillisecs === 0) { | |
func(); | |
} else { | |
timeoutID = window.setTimeout(func, delayMillisecs); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment