Created
August 5, 2011 15:57
-
-
Save nowhereman/1127840 to your computer and use it in GitHub Desktop.
Transform all select tag, legacy behaviour of https://gist.github.com/954934
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 Pimp my Drop Down List | |
// @description Instant auto-completion for any drop down lists (<select>) on any page | |
// @author Nowhere Man | |
// @version 0.2.9dev | |
// @homepage https://gist.github.com/954934/#file_readme.md | |
// @updateURL https://raw.github.com/gist/954934/combo.user.js | |
// @include https://* | |
// @include http://* | |
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js | |
// @require https://raw.github.com/gist/954934/jquery.contextMenu.js | |
// @require https://raw.github.com/gist/954934/jquery.combo.dependencies.js | |
// @require https://raw.github.com/gist/954934/jquery.combo.js | |
// @resource text-bg.b64 https://raw.github.com/gist/954934/text-bg.b64 | |
// @resource trigger.b64 https://raw.github.com/gist/954934/trigger.b64 | |
// @resource default.css https://raw.github.com/gist/954934/default.css | |
// @resource combo.css https://raw.github.com/gist/954934/combo.css | |
// @resource usage.css https://raw.github.com/gist/954934/usage.css | |
// ==/UserScript== | |
jQuery.noConflict(); | |
(function($) { | |
var head = document.getElementsByTagName("head")[0]; | |
var imgs = {}; | |
function requireImg(resourceName) { | |
var img = GM_getResourceURL(resourceName); | |
imgs[resourceName] = img; | |
} | |
function requireBase64Img(resourceName, type) { | |
if (!type) | |
type = 'gif'; | |
var img = "data:image/" + type + ";base64," + GM_getResourceText(resourceName); | |
resourceName = resourceName.replace(/^(.+\.)b64$/,'$1' + type); | |
imgs[resourceName] = img; | |
} | |
function requireCSS(resourceName) { | |
var style = document.createElement('style'); | |
style.setAttribute('type', 'text/css'); | |
var css = GM_getResourceText(resourceName); | |
$.each(imgs, function(imgName, imgBase64) { | |
css = css.replace(imgName, imgBase64); | |
}); | |
style.innerHTML = css; | |
head.appendChild(style); | |
} | |
requireBase64Img('text-bg.b64'); | |
requireBase64Img('trigger.b64'); | |
requireCSS('combo.css'); | |
requireCSS('default.css'); | |
requireCSS('usage.css'); | |
// Persistence stuff | |
function deserialize(name) { | |
var s = GM_getValue(name); | |
if (s === undefined) { | |
return {}; | |
} | |
else { | |
return JSON.parse(s); | |
} | |
} | |
function serialize(name, value) { | |
GM_setValue(name, JSON.stringify(value)); | |
} | |
// Default config of Comb'O plugin | |
var conf = { | |
accentsSensitive: false, | |
triggerSelected: true, | |
highlightTerm: true, | |
liquidFilter: true, | |
liquidSorting: true, | |
keyPressDelay: 200, | |
lazyLoading: true | |
}; | |
// If Firefox version is below 4.0 (Gecko engine below to 2.0), we adjust the config to preserve performances | |
if ($.browser.mozilla && $.browser.version < "2") { | |
conf.liquidFilter = false; | |
conf.liquidSorting = false; | |
conf.keyPressDelay = 300; | |
} | |
$.extend(conf);//debug | |
// $.extend(conf, deserialize('config')); // Disabled for the moment | |
// TODO make a dynamic form to update the global config | |
serialize('config', conf); | |
// Usage of Comb'O plugin | |
function comboify() { | |
// Add id attribute to select elements who haven't | |
$("select:not([id])[name]").attr("id", function(index, attr) { | |
return this.name; | |
}); | |
// Transform all select tag, who haven't 'skip-combo' class, to combobox | |
$("select[id][multiple!=true]:visible:not('.skip-combo')").combo(conf); | |
// Context menu stuff | |
$(".combo .icon").contextMenu('restore-select', { | |
'Restore Drop Down List': { | |
click: function(element){ | |
element.data("context-menu").remove(); | |
element.removeData("context-menu"); | |
element.parent(".combo").find("select:first").addClass("skip-combo").combo().destroy(); | |
}, | |
klass: "combo-context-menu" | |
}, | |
'Options': { | |
click: function(element){ | |
var comboBox = element.parent(".combo").find("select:first"); | |
// include margin so it can be used to offset from page border. | |
var elPos = element.offset(); | |
var mWidth = element.outerWidth(true), | |
mHeight = element.outerHeight(true), | |
xPos = ((elPos.left - window.scrollX) + mWidth < window.innerWidth) ? elPos.left : elPos.left - mWidth, | |
yPos = ((elPos.top - window.scrollY) + mHeight < window.innerHeight) ? elPos.top : elPos.top - mHeight; | |
var formId = comboBox.attr('id') + "__options"; | |
var formOptions = $("#" + formId);// search if form is already present | |
if(formOptions.length == 0) { | |
formOptions = $("<form id='" + formId + "' class='combo-options'><h3>Options :</h3><input type='checkbox' name='fuzzy-search' /> <label for='fuzzy-search'>Fuzzy Search <small>(slow)</small></label><br /><br /><input type='submit' value='Save'> or <a href='#' class='close-form-options'>close</a></form>").appendTo('body'); | |
} else { | |
formOptions.show(); | |
} | |
formOptions.find('[name=fuzzy-search]').attr('checked', comboBox.combo().config.liquidSorting); | |
$('form.combo-options').submit(function(e){ | |
var fuzzySearch = $(this).find('[name=fuzzy-search]').attr('checked'); | |
var fuzzySearchOption = (fuzzySearch) ? true : false; | |
// GM_log(fuzzySearchOption); //debug | |
comboBox.combo().config.liquidSorting = fuzzySearchOption; | |
comboBox.combo().config.liquidFilter = fuzzySearchOption; | |
// comboBox.combo({liquidSorting: fuzzySearchOption, liquidFilter: fuzzySearchOption}); // Don't work ! | |
// $.extend(comboBox.combo.config,{liquidSorting: fuzzySearchOption, liquidFilter: fuzzySearchOption}); // TODO test this instead | |
// GM_log(comboBox.combo().config.liquidFilter);//debug | |
$(this).hide(); | |
e.preventDefault(); | |
}) | |
.css({ | |
top: yPos + 'px', | |
left: xPos + 'px' | |
}) | |
.find('.close-form-options').click(function(e) { | |
$(this).parent("form").hide(); | |
e.preventDefault(); | |
}); | |
} | |
} | |
}); | |
// Add a context menu to all select tag who have a 'skip-combo' class | |
$("select.skip-combo[id][multiple!=true]:visible").contextMenu('restore-combo', { | |
'Pimp this Drop Down List': { | |
click: function(element){ | |
element.data("context-menu").remove(); | |
element.removeData("context-menu"); | |
element.removeClass("skip-combo").combo(conf); | |
}, | |
klass: "combo-context-menu" | |
} | |
}); | |
} | |
// Convert select tags into combobox when DOM content is loaded | |
function loadedHandler(event) { | |
window.setTimeout( function() { | |
comboify(); | |
// Check for new select tags to convert them into combobox | |
var timer; | |
function modifiedHandler(event) { | |
if (timer != null) { | |
clearTimeout(timer); | |
} | |
timer = window.setTimeout(comboify, 750); | |
} | |
document.addEventListener("DOMNodeInserted", modifiedHandler, false); | |
document.addEventListener("mouseup", modifiedHandler, false); | |
document.addEventListener("keyup", modifiedHandler, false); | |
}, 1000); | |
} | |
if(document.readyState) { | |
if($.browser.webkit) { | |
document.addEventListener("DOMContentLoaded", loadedHandler, false); | |
} else { | |
loadedHandler(); | |
} | |
} else { | |
window.addEventListener("load", loadedHandler, false); | |
} | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment