I have this plugin that I have finally finished the big pieces of, there's one or two minor details that are not yet implemented do to lack of a decision yet but everything else is there.
I wrote it and can follow fine but I feel it reads very haphazardly. Could someone with fresh eyes help me make this into a more production level plugin? For clarity, I'm not asking for it be rewritten, just if you see something that could be made better, a nudge in that direction would be super helpful.
;(function($, undefined) {
var defaults = {
onInit : function () {},
onDestroy: function () {},
onClick : function () {},
onHover : function(id, state) { this.setTransient(id, 'blue'); },
noHover : function(id, state) { this.reset(id); }
}
var pubAPI = {
set : function(id, style) {
this.state[id].style = style;
this.reset(id);
},
reset : function(id) {
applyStyle.call(this, id);
},
setTransient : function (id, style) {
applyStyle.call(this, id, style);
},
resetState : function (id) {
this.state[id].style = this.state[id].dFault;
this.reset(id);
},
destroy : function () {
this.settings.onDestroy();
unbindEvents();
},
getInstance : function () {
return this;
}
}
var Clicklight = function(options) {
this.settings = $.extend({}, defaults, options);
this.state = {};
}
var init = function(elem, inst) {
var id = idCheck(elem);
if (id) {
if (!inst.state[id]) {
var color = $(elem).css('color');
inst.state[id] = {
group : [],
dFault : color,
style : color
}
}
inst.state[id].group.push($(elem));
bindEvent($(elem), inst, id);
inst.settings.onInit();
return inst;
} else {
console.log('ERROR: No \'data-cl-uid\' found on', elem, '-this element was not included');
return undefined; // data attr can't hold undefined, forces error later on
}
}
var idCheck = function(elem) {
return $(elem).attr('data-cl-uid') ?
$(elem).attr('data-cl-uid') : null;
}
var bindEvent = function($elem, inst, id) {
$elem.on('click.clicklight', function () {
inst.settings.onClick.call(inst, id, inst.state[id]);
}).on('mouseenter.clicklight', function () {
inst.settings.onHover.call(inst, id, inst.state[id]);
}).on('mouseleave.clicklight', function() {
inst.settings.noHover.call(inst, id, inst.state[id]);
});
}
var unbindEvents = function($elem) {
// fill this in
}
var applyStyle = function (id, style) {
var group = this.state[id].group;
if (!style)
style = this.state[id].style
for (var i = 0; i < group.length; i++)
group[i].css('color', style);
}
var getInst = function($elem) {
var inst = null;
$elem.each(function() {
if (!$.data(this, 'cl-instance'))
return true
else if (!($.data(this, 'cl-instance') instanceof Clicklight)) {
console.log('ERROR: Invalid instance found on', this);
return true;
} else {
inst = $.data(this, 'cl-instance');
return false;
}
});
return inst;
}
$.extend(Clicklight.prototype, pubAPI);
$.fn.clicklight = function (option) {
var args = arguments;
if (typeof option === 'object' || !option) {
var inst = null;
return this.each(function() {
if (!inst)
inst = new Clicklight(option);
if (!$.data(this, 'cl-instance'))
$.data(this, 'cl-instance', init(this, inst));
else
console.log('ERROR: Cannot create a duplicate instance for ',this);
});
} else if (typeof option === 'string' && option in pubAPI) {
var inst = getInst(this);
if (inst) {
if (typeof inst[option] === 'function')
return inst[option].apply(inst, Array.prototype.slice.call(args, 1));
else
console.log('ERROR: No method found with name', option);
} else
console.log('ERROR: No instance found in selection', this);
} else
console.log('ERROR: Invalid call of clicklight with argument', option);
return this;
}
})(jQuery, undefined);
For those that want to see it in action, I have it running on this test page.