Skip to content

Instantly share code, notes, and snippets.

@nowhereman
Created August 5, 2011 15:57
Show Gist options
  • Save nowhereman/1127840 to your computer and use it in GitHub Desktop.
Save nowhereman/1127840 to your computer and use it in GitHub Desktop.
Transform all select tag, legacy behaviour of https://gist.github.com/954934
// ==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