I'm trying to get my head around the 11,000+ lines of JavaScript code in FullCalendar in order to be able to build new features into it, and so I am trying to understand the various patterns that are being used, especially the beginning here:
FullCalendar v2.4.0:
(function(factory) {
if (typeof define === 'function' && define.amd) {
define([ 'jquery', 'moment' ], factory);
}
else if (typeof exports === 'object') { // Node/CommonJS
module.exports = factory(require('jquery'), require('moment'));
}
else {
factory(jQuery, moment);
}
})(function($, moment) {
;;
var fc = $.fullCalendar = { version: "2.4.0" };
var fcViews = fc.views = {};
$.fn.fullCalendar = function(options) {
var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
var res = this; // what this function will return (this jQuery object by default)
this.each(function(i, _element) { // loop each DOM element involved
var element = $(_element);
var calendar = element.data('fullCalendar'); // get the existing calendar object (if any)
var singleRes; // the returned value of this single method call
// a method call
if (typeof options === 'string') {
if (calendar && $.isFunction(calendar[options])) {
singleRes = calendar[options].apply(calendar, args);
if (!i) {
res = singleRes; // record the first method call result
}
if (options === 'destroy') { // for the destroy method, must remove Calendar object data
element.removeData('fullCalendar');
}
}
}
// a new calendar initialization
else if (!calendar) { // don't initialize twice
calendar = new Calendar(element, options);
element.data('fullCalendar', calendar);
calendar.render();
}
});
return res;
};
...
In order to understand what each line of this code is for, I'm trying to build a simplified copy of the it here:
http://jsfiddle.net/edwardtanguay/mbs5uafd/2
What do I need to change to this jsfiddle to get it to the point that it is functioning as FullCalendar where <div id='calendar'></div>
produces HTML text in the same way that the FullCalendar module does?
I need to get it to this point so that I can begin building on it and thus coming into an understanding of how the FullCalendar module works in detail.
I've added questions regarding specific lines of code which are not clear.
// where exactly is factory being passed in?
(function(factory) {
// I understand this code to be part of the
// JavaScript specification "Asynchronous Module Definition"
// and seems to be defining jQuery and moment.js as dependencies
// but they are available anyway so why do they need to be defined as dependencies here?
// where is the variable "define" coming from?
if (typeof define === 'function' && define.amd) {
define([ 'jquery', 'moment' ], factory);
}
// where is is the variable "exports" being defined
else if (typeof exports === 'object') { // Node/CommonJS
module.exports = factory(require('jquery'), require('moment'));
}
else {
factory(jQuery, moment);
}
})(function($, moment) {
// this I understand as simply defining an object "fullCalendar" in the jQuery scope
// but what does it have to do with the $.fn.fullCalendar below?
var fc = $.fullCalendar = { version: "2.4.0" };
$.fn.fullCalendar = function() {
return 'calendar test works';
};
});
$(function() {
$('#calendar').html('jquery works');
$('#calendar').fullCalendar();
});
ANSWER
Here are my notes on this first block of code for anyone trying to figure this out, basically the first block of code is just making sure that jQuery and moment are loaded and is flexible enough to load them in different ways.
(function(factoryWhatever) {
// ET: this is checking for AMD script such as require.js, is undefined here and skips through
// ET: it is just making sure that jquery and moment are loaded
if (typeof define === 'function' && define.amd) {
define([ 'jquery', 'moment' ], factoryWhatever);
}
// ET: this is checking for Node or CommonJS which can make sure that jquery and moment are loaded
else if (typeof exports === 'object') { // Node/CommonJS
module.exports = factoryWhatever(require('jquery'), require('moment'));
}
else {
// ET: if neither an AMD script or Node/CommonJS is running, then it will just execute the massively long function below
// ET: passing in jQuery and moment which will be called "$" and "moment" inside the function
factoryWhatever(jQuery, moment);
}
// ET: this function from line 23 to 11167 is the whole fullCalendar application which runs with
// ET: the two dependencies jQuery and moment
})(function($, moment) {
...
});
And here is the simplified code that basically shows how the FullCalendar code is structured:
http://jsfiddle.net/edwardtanguay/xw0s38un/2
(function(factory) {
factory(jQuery, moment);
})(function($, moment) {
var fc = $.fullCalendar = { version: "2.4.0" };
$.fn.fullCalendar = function(options) {
var res = this;
res.html('the calendar');
return res;
};
});
$(function() {
$('#calendar').fullCalendar();
});