Dynamic Plugin Extensions
I'm looking for techniques to allow a jquery plugin or jquery-based javascript library to automatically and dynamically add extensions to itself based on the current environment it finds itself within. Basically, I want to be able to reuse certain useful functions from other plugins if other plugins are loaded on a page. If my plugin detects they are not loaded, then I want to load my own version of those features.
For instance, my plugin needs date parsing and formatting features. One popular way of doing this is to use DateJS's parse() and toString(). But DateJS is a fairly heavyweight plugin, and my plugin doesn't need anywhere near the features it has. Other plugins have some similar features, such as UI DatePicker, FullCalendar, etc. If any of those plugins are in use on a page, I'd rather not load excessive and redundant code in my plugin and just use the other plugin's functions instead.
So what I'd like to do is provide my own simplified version of parse() and format() in an external file from the main plugin file. If no other plugins are in use that provide the required parse() and format() features, then the main plugin file would load my dates extension plugin.
If my main plugin detects that any of the plugins DateJS, UI DatePicker, or FullCalendar are loaded, then it would load a simple wrapper extension for it that would provide the required parse() and format() functions. These functions would basically just call the other plugin's parsing and formatting functions.
Questions
- What would be the best way to do feature detection to determine if a plugin is loaded?
- How would I dynamically load the proper additional extension script?
- How would I make sure that I don't load multiple extensions, overriding each other?
- Are there other plugins that extend themselves? I'd like to examine them to see how they are doing it.
Detailed Example
If it helps to understand the question better, I'm envisioning files like this:
myplugin.js
myplugin-dates.js
myplugin-wrap-datejs.js
myplugin-wrap-datepicker.js
myplugin-wrap-fullcalendar.js
The file myplugin.js would be something like this (note this isn't a real jquery plugin, but more of a globally registered library):
var MYPLUG = (function (parent, $) {
var MYPLUG = parent;
// Public functions
MYPLUG.doSomething = function(dateString) {
...
var date = MYPLUG.Dates.parse(dateString);
...
var prettyDate = MYPLUG.Dates.format(date);
...
};
return parent;
}(MYPLUG || {}, jQuery));
The file myplugin-dates.js would look something like this:
var MYPLUG = (function (parent, $) {
var Dates = parent.Dates = parent.Dates || {};
Dates.parse = function(dateString) {
// Custom code to parse dateString to a date
}
Dates.format = function(dateObj) {
// Custom code to format dateObj as a string
}
return parent;
}(MYPLUG || {}, jQuery));
Finally, the file myplugin-wrap-fullcalendar.js plugin-wrapping extension might look like this:
var MYPLUG = (function (parent, $) {
var Dates = parent.Dates = parent.Dates || {};
Dates.parse = function(dateString) {
return $.fullCalendar.parseDate(dateString);
}
Dates.format = function(dateObj) {
return $.fullCalendar.formatDate(dateObj, "mm/dd/yy");
}
return parent;
}(MYPLUG || {}, jQuery));