Updating jQuery.plugin.js from jQuery.Calendars v2.2.0

This commit is contained in:
Benedek Farkas
2025-10-01 21:45:25 +02:00
parent 4be3049686
commit 01c4aba522
3 changed files with 345 additions and 248 deletions

View File

@@ -1,9 +1,11 @@
/* Simple JavaScript Inheritance
/* globals JQClass */
/*! Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(){
'use strict';
var initializing = false;
// The base JQClass implementation (does nothing)
@@ -16,37 +18,44 @@
JQClass.extend = function extender(prop) {
var base = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
// Instantiate a base class (but only create the instance, don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
for (var name in prop) { // jshint loopfunc:true
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == 'function' &&
typeof base[name] == 'function' ?
(function(name, fn){
return function() {
if (typeof prop[name] === 'function' && typeof base[name] === 'function') {
prototype[name] = (function (name, fn) {
return function () {
var __super = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = function(args) {
// Add a new ._super() method that is the same method but on the super-class
this._super = function (args) {
return base[name].apply(this, args || []);
};
var ret = fn.apply(this, arguments);
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
// The method only needs to be bound temporarily, so we remove it when we're done executing
this._super = __super;
return ret;
};
})(name, prop[name]) :
prop[name];
})(name, prop[name]);
// Check if we're overwriting existing default options.
} else if (typeof prop[name] === 'object' && typeof base[name] === 'object' && name === 'defaultOptions') {
var obj1 = base[name];
var obj2 = prop[name];
var obj3 = {};
var key;
for (key in obj1) { // jshint forin:false
obj3[key] = obj1[key];
}
for (key in obj2) { // jshint forin:false
obj3[key] = obj2[key];
}
prototype[name] = obj3;
} else {
prototype[name] = prop[name];
}
}
// The dummy class constructor
@@ -69,13 +78,31 @@
return JQClass;
};
})();
/*! Abstract base class for collection plugins v1.0.2.
Written by Keith Wood (wood.keith{at}optusnet.com.au) December 2013.
Licensed under the MIT license (http://keith-wood.name/licence.html). */
(function($) { // Ensure $, encapsulate
'use strict';
/** Abstract base class for collection plugins v1.0.1.
Written by Keith Wood (kbwood{at}iinet.com.au) December 2013.
Licensed under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license.
@module $.JQPlugin
/** <p>Abstract base class for collection plugins v1.0.2.</p>
<p>Written by Keith Wood (wood.keith{at}optusnet.com.au) December 2013.</p>
<p>Licensed under the MIT license (http://keith-wood.name/licence.html).</p>
<p>Use {@link $.JQPlugin.createPlugin} to create new plugins using this framework.</p>
<p>This base class provides common functionality such as:</p>
<ul>
<li>Creates jQuery bridge - allowing you to invoke your plugin on a collection of elements.</li>
<li>Handles initialisation including reading settings from metadata -
an instance object is attached to the affected element(s) containing all the necessary data.</li>
<li>Handles option retrieval and update - options can be set through default values,
through inline metadata, or through instantiation settings.<br>
Metadata is specified as an attribute on the element:
<code>data-&lt;pluginName>="&lt;option name>: '&lt;value>', ..."</code>.
Dates should be specified as strings in this format: <code>'new Date(y, m-1, d)'</code>.</li>
<li>Handles method calling - inner functions starting with '_'are inaccessible,
whereas others can be called via <code>$(selector).pluginName('functionName')</code>.</li>
<li>Handles plugin destruction - removing all trace of the plugin.</li>
</ul>
@module JQPlugin
@abstract */
JQClass.classes.JQPlugin = JQClass.extend({
@@ -85,34 +112,37 @@
/** Default options for instances of this plugin (default: {}).
@example defaultOptions: {
selectedClass: 'selected',
triggers: 'click'
} */
selectedClass: 'selected',
triggers: 'click'
} */
defaultOptions: {},
/** Options dependent on the locale.
Indexed by language and (optional) country code, with '' denoting the default language (English/US).
Normally additional languages would be provided as separate files to all them to be included as needed.
@example regionalOptions: {
'': {
greeting: 'Hi'
}
} */
'': {
greeting: 'Hi'
}
} */
regionalOptions: {},
/** Names of getter methods - those that can't be chained (default: []).
@example _getters: ['activeTab'] */
_getters: [],
/** Whether or not a deep merge should be performed when accumulating options.
The default is <code>true</code> but can be overridden in a sub-class. */
deepMerge: true,
/** Retrieve a marker class for affected elements.
@private
In the format: <code>is-&lt;pluginName&gt;</code>.
@protected
@return {string} The marker class. */
_getMarker: function() {
return 'is-' + this.name;
},
/** Initialise the plugin.
Create the jQuery bridge - plugin name <code>xyz</code>
produces <code>$.xyz</code> and <code>$.fn.xyz</code>. */
produces singleton <code>$.xyz</code> and collection function <code>$.fn.xyz</code>.
@protected */
_init: function() {
// Apply default localisations
$.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {});
@@ -123,56 +153,47 @@
// Expose jQuery collection plugin
$.fn[jqName] = function(options) {
var otherArgs = Array.prototype.slice.call(arguments, 1);
if ($[jqName]._isNotChained(options, otherArgs)) {
return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs));
}
return this.each(function() {
var inst = this;
var returnValue = this;
this.each(function () {
if (typeof options === 'string') {
if (options[0] === '_' || !$[jqName][options]) {
throw 'Unknown method: ' + options;
}
$[jqName][options].apply($[jqName], [this].concat(otherArgs));
}
else {
var methodValue = $[jqName][options].apply($[jqName], [this].concat(otherArgs));
if (methodValue !== inst && methodValue !== undefined) {
returnValue = methodValue;
return false;
}
} else {
$[jqName]._attach(this, options);
}
});
return returnValue;
};
},
/** Set default values for all subsequent instances.
@param options {object} The new default options.
@example $.plugin.setDefauls({name: value}) */
/** Set default options for all subsequent instances.
@param {object} options The new default options.
@example $.pluginName.setDefaults({name: value, ...}) */
setDefaults: function(options) {
$.extend(this.defaultOptions, options || {});
},
/** Determine whether a method is a getter and doesn't permit chaining.
@private
@param name {string} The method name.
@param otherArgs {any[]} Any other arguments for the method.
@return {boolean} True if this method is a getter, false otherwise. */
_isNotChained: function(name, otherArgs) {
if (name === 'option' && (otherArgs.length === 0 ||
(otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) {
return true;
}
return $.inArray(name, this._getters) > -1;
},
/** Initialise an element. Called internally only.
Adds an instance object as data named for the plugin.
@param elem {Element} The element to enhance.
@param options {object} Overriding settings. */
Override {@linkcode module:JQPlugin~_postAttach|_postAttach} for plugin-specific processing.
@private
@param {Element} elem The element to enhance.
@param {object} options Overriding settings. */
_attach: function(elem, options) {
elem = $(elem);
if (elem.hasClass(this._getMarker())) {
return;
}
elem.addClass(this._getMarker());
options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {});
var inst = $.extend({name: this.name, elem: elem, options: options},
this._instSettings(elem, options));
options = $.extend(this.deepMerge, {}, this.defaultOptions, this._getMetadata(elem), options || {});
var inst = $.extend({name: this.name, elem: elem, options: options}, this._instSettings(elem, options));
elem.data(this.name, inst); // Save instance against element
this._postAttach(elem, inst);
this.option(elem, options);
@@ -180,48 +201,59 @@
/** Retrieve additional instance settings.
Override this in a sub-class to provide extra settings.
@param elem {jQuery} The current jQuery element.
@param options {object} The instance options.
These are added directly to the instance object.
Default attributes of an instance object are shown as properties below:
@protected
@param {jQuery} elem The current jQuery element.
@param {object} options The instance options.
@return {object} Any extra instance values.
@property {Element} elem The element to which this instance applies.
@property {string} name The name of this plugin.
@property {object} options The accumulated options for this instance.
@example _instSettings: function(elem, options) {
return {nav: elem.find(options.navSelector)};
} */
_instSettings: function(elem, options) {
return {nav: elem.find(options.navSelector)};
} */
_instSettings: function(elem, options) { // jshint unused:false
return {};
},
/** Plugin specific post initialisation.
Override this in a sub-class to perform extra activities.
@param elem {jQuery} The current jQuery element.
@param inst {object} The instance settings.
This is where you would implement your plugin's main functionality.
@protected
@param {jQuery} elem The current jQuery element.
@param {object} inst The instance settings.
@example _postAttach: function(elem, inst) {
elem.on('click.' + this.name, function() {
...
});
} */
_postAttach: function(elem, inst) {
elem.on('click.' + this.name, function() {
...
});
} */
_postAttach: function(elem, inst) { // jshint unused:false
},
/** Retrieve metadata configuration from the element.
Metadata is specified as an attribute:
<code>data-&lt;plugin name>="&lt;setting name>: '&lt;value>', ..."</code>.
Dates should be specified as strings in this format: 'new Date(y, m-1, d)'.
<code>data-&lt;pluginName>="&lt;option name>: '&lt;value>', ..."</code>.
Dates should be specified as strings in this format: <code>'new Date(y, m-1, d)'</code>.
@private
@param elem {jQuery} The source element.
@param {jQuery} elem The source element.
@return {object} The inline configuration or {}. */
_getMetadata: function(elem) {
try {
var data = elem.data(this.name.toLowerCase()) || '';
data = data.replace(/'/g, '"');
data = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) {
data = data.replace(/(\\?)'/g, function(e, t) {
return t ? '\'' : '"';
}).replace(/([a-zA-Z0-9]+):/g, function(match, group, i) {
var count = data.substring(0, i).match(/"/g); // Handle embedded ':'
return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':');
});
}).replace(/\\:/g, ':');
data = $.parseJSON('{' + data + '}');
for (var name in data) { // Convert dates
var value = data[name];
if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) {
data[name] = eval(value);
for (var key in data) {
if (data.hasOwnProperty(key)) {
var value = data[key];
if (typeof value === 'string' && value.match(/^new Date\(([-0-9,\s]*)\)$/)) { // Convert dates
data[key] = eval(value); // jshint ignore:line
}
}
}
return data;
@@ -232,32 +264,38 @@
},
/** Retrieve the instance data for element.
@param elem {Element} The source element.
@return {object} The instance data or {}. */
@protected
@param {Element} elem The source element.
@return {object} The instance data or <code>{}</code> if none. */
_getInst: function(elem) {
return $(elem).data(this.name) || {};
},
/** Retrieve or reconfigure the settings for a plugin.
@param elem {Element} The source element.
@param name {object|string} The collection of new option values or the name of a single option.
@param [value] {any} The value for a single named option.
If new settings are provided they are applied to the instance options.
If an option name only is provided the value of that option is returned.
If no name or value is provided, all options are returned.
Override {@linkcode module:JQPlugin~_optionsChanged|_optionsChanged}
for plugin-specific processing when option values change.
@param {Element} elem The source element.
@param {object|string} [name] The collection of new option values or the name of a single option.
@param {any} [value] The value for a single named option.
@return {any|object} If retrieving a single value or all options.
@example $(selector).plugin('option', 'name', value)
$(selector).plugin('option', {name: value, ...})
var value = $(selector).plugin('option', 'name')
var options = $(selector).plugin('option') */
@example $(selector).plugin('option', 'name', value) // Set one option
$(selector).plugin('option', {name: value, ...}) // Set multiple options
var value = $(selector).plugin('option', 'name') // Get one option
var options = $(selector).plugin('option') // Get all options */
option: function(elem, name, value) {
elem = $(elem);
var inst = elem.data(this.name);
if (!name || (typeof name === 'string' && value == null)) {
var options = (inst || {}).options;
var options = name || {};
if (!name || (typeof name === 'string' && typeof value === 'undefined')) {
options = (inst || {}).options;
return (options && name ? options[name] : options);
}
if (!elem.hasClass(this._getMarker())) {
return;
}
var options = name || {};
if (typeof name === 'string') {
options = {};
options[name] = value;
@@ -265,24 +303,25 @@
this._optionsChanged(elem, inst, options);
$.extend(inst.options, options);
},
/** Plugin specific options processing.
Old value available in <code>inst.options[name]</code>, new value in <code>options[name]</code>.
Override this in a sub-class to perform extra activities.
@param elem {jQuery} The current jQuery element.
@param inst {object} The instance settings.
@param options {object} The new options.
@protected
@param {jQuery} elem The current jQuery element.
@param {object} inst The instance settings.
@param {object} options The new options.
@example _optionsChanged: function(elem, inst, options) {
if (options.name != inst.options.name) {
elem.removeClass(inst.options.name).addClass(options.name);
}
} */
_optionsChanged: function(elem, inst, options) {
if (options.name != inst.options.name) {
elem.removeClass(inst.options.name).addClass(options.name);
}
} */
_optionsChanged: function(elem, inst, options) { // jshint unused:false
},
/** Remove all trace of the plugin.
Override <code>_preDestroy</code> for plugin-specific processing.
@param elem {Element} The source element.
Override {@linkcode module:JQPlugin~_preDestroy|_preDestroy} for plugin-specific processing.
@param {Element} elem The source element.
@example $(selector).plugin('destroy') */
destroy: function(elem) {
elem = $(elem);
@@ -294,41 +333,46 @@
},
/** Plugin specific pre destruction.
It is invoked as part of the {@linkcode module:JQPlugin~destroy|destroy} processing.
Override this in a sub-class to perform extra activities and undo everything that was
done in the <code>_postAttach</code> or <code>_optionsChanged</code> functions.
@param elem {jQuery} The current jQuery element.
@param inst {object} The instance settings.
done in the {@linkcode module:JQPlugin~_postAttach|_postAttach} or
{@linkcode module:JQPlugin~_optionsChanged|_optionsChanged} functions.
@protected
@param {jQuery} elem The current jQuery element.
@param {object} inst The instance settings.
@example _preDestroy: function(elem, inst) {
elem.off('.' + this.name);
} */
_preDestroy: function(elem, inst) {
elem.off('.' + this.name);
} */
_preDestroy: function(elem, inst) { // jshint unused:false
}
});
/** Convert names from hyphenated to camel-case.
@private
@param value {string} The original hyphenated name.
@param {string} value The original hyphenated name.
@return {string} The camel-case version. */
function camelCase(name) {
return name.replace(/-([a-z])/g, function(match, group) {
return group.toUpperCase();
});
}
/** Expose the plugin base.
@namespace "$.JQPlugin" */
@namespace $.JQPlugin */
$.JQPlugin = {
/** Create a new collection plugin.
@memberof "$.JQPlugin"
@param [superClass='JQPlugin'] {string} The name of the parent class to inherit from.
@param overrides {object} The property/function overrides for the new class.
@example $.JQPlugin.createPlugin({
name: 'tabs',
defaultOptions: {selectedClass: 'selected'},
_initSettings: function(elem, options) { return {...}; },
_postAttach: function(elem, inst) { ... }
}); */
@memberof $.JQPlugin
@param {string} [superClass='JQPlugin'] The name of the parent class to inherit from.
@param {object} overrides The property/function overrides for the new class.
See {@link module:JQPlugin|JQPlugin} for the base functionality.
@example $.JQPlugin.createPlugin({ // Define the plugin
name: 'tabs',
defaultOptions: {selectedClass: 'selected'},
_initSettings: function(elem, options) { return {...}; },
_postAttach: function(elem, inst) { ... }
});
$('selector').tabs(); // And instantiate it */
createPlugin: function(superClass, overrides) {
if (typeof superClass === 'object') {
overrides = superClass;
@@ -337,7 +381,7 @@
superClass = camelCase(superClass);
var className = camelCase(overrides.name);
JQClass.classes[className] = JQClass.classes[superClass].extend(overrides);
new JQClass.classes[className]();
new JQClass.classes[className](); // jshint ignore:line
}
};

View File

@@ -3,12 +3,14 @@
** Any changes made directly to this file will be overwritten next time its asset group is processed by Gulp.
*/
/* Simple JavaScript Inheritance
/* globals JQClass */
/*! Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function () {
'use strict';
var initializing = false;
// The base JQClass implementation (does nothing)
window.JQClass = function () { };
@@ -17,32 +19,44 @@
// Create a new JQClass that inherits from this class
JQClass.extend = function extender(prop) {
var base = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
// Instantiate a base class (but only create the instance, don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == 'function' &&
typeof base[name] == 'function' ?
(function (name, fn) {
if (typeof prop[name] === 'function' && typeof base[name] === 'function') {
prototype[name] = (function (name, fn) {
return function () {
var __super = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
// Add a new ._super() method that is the same method but on the super-class
this._super = function (args) {
return base[name].apply(this, args || []);
};
var ret = fn.apply(this, arguments);
// The method only need to be bound temporarily, so we
// remove it when we're done executing
// The method only needs to be bound temporarily, so we remove it when we're done executing
this._super = __super;
return ret;
};
})(name, prop[name]) :
prop[name];
})(name, prop[name]);
}
else if (typeof prop[name] === 'object' && typeof base[name] === 'object' && name === 'defaultOptions') {
var obj1 = base[name];
var obj2 = prop[name];
var obj3 = {};
var key;
for (key in obj1) {
obj3[key] = obj1[key];
}
for (key in obj2) {
obj3[key] = obj2[key];
}
prototype[name] = obj3;
}
else {
prototype[name] = prop[name];
}
}
// The dummy class constructor
function JQClass() {
@@ -60,11 +74,30 @@
return JQClass;
};
})();
/*! Abstract base class for collection plugins v1.0.2.
Written by Keith Wood (wood.keith{at}optusnet.com.au) December 2013.
Licensed under the MIT license (http://keith-wood.name/licence.html). */
(function ($) {
/** Abstract base class for collection plugins v1.0.1.
Written by Keith Wood (kbwood{at}iinet.com.au) December 2013.
Licensed under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license.
@module $.JQPlugin
'use strict';
/** <p>Abstract base class for collection plugins v1.0.2.</p>
<p>Written by Keith Wood (wood.keith{at}optusnet.com.au) December 2013.</p>
<p>Licensed under the MIT license (http://keith-wood.name/licence.html).</p>
<p>Use {@link $.JQPlugin.createPlugin} to create new plugins using this framework.</p>
<p>This base class provides common functionality such as:</p>
<ul>
<li>Creates jQuery bridge - allowing you to invoke your plugin on a collection of elements.</li>
<li>Handles initialisation including reading settings from metadata -
an instance object is attached to the affected element(s) containing all the necessary data.</li>
<li>Handles option retrieval and update - options can be set through default values,
through inline metadata, or through instantiation settings.<br>
Metadata is specified as an attribute on the element:
<code>data-&lt;pluginName>="&lt;option name>: '&lt;value>', ..."</code>.
Dates should be specified as strings in this format: <code>'new Date(y, m-1, d)'</code>.</li>
<li>Handles method calling - inner functions starting with '_'are inaccessible,
whereas others can be called via <code>$(selector).pluginName('functionName')</code>.</li>
<li>Handles plugin destruction - removing all trace of the plugin.</li>
</ul>
@module JQPlugin
@abstract */
JQClass.classes.JQPlugin = JQClass.extend({
/** Name to identify this plugin.
@@ -72,30 +105,33 @@
name: 'plugin',
/** Default options for instances of this plugin (default: {}).
@example defaultOptions: {
selectedClass: 'selected',
triggers: 'click'
} */
selectedClass: 'selected',
triggers: 'click'
} */
defaultOptions: {},
/** Options dependent on the locale.
Indexed by language and (optional) country code, with '' denoting the default language (English/US).
Normally additional languages would be provided as separate files to all them to be included as needed.
@example regionalOptions: {
'': {
greeting: 'Hi'
}
} */
'': {
greeting: 'Hi'
}
} */
regionalOptions: {},
/** Names of getter methods - those that can't be chained (default: []).
@example _getters: ['activeTab'] */
_getters: [],
/** Whether or not a deep merge should be performed when accumulating options.
The default is <code>true</code> but can be overridden in a sub-class. */
deepMerge: true,
/** Retrieve a marker class for affected elements.
@private
In the format: <code>is-&lt;pluginName&gt;</code>.
@protected
@return {string} The marker class. */
_getMarker: function () {
return 'is-' + this.name;
},
/** Initialise the plugin.
Create the jQuery bridge - plugin name <code>xyz</code>
produces <code>$.xyz</code> and <code>$.fn.xyz</code>. */
produces singleton <code>$.xyz</code> and collection function <code>$.fn.xyz</code>.
@protected */
_init: function () {
// Apply default localisations
$.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {});
@@ -106,51 +142,45 @@
// Expose jQuery collection plugin
$.fn[jqName] = function (options) {
var otherArgs = Array.prototype.slice.call(arguments, 1);
if ($[jqName]._isNotChained(options, otherArgs)) {
return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs));
}
return this.each(function () {
var inst = this;
var returnValue = this;
this.each(function () {
if (typeof options === 'string') {
if (options[0] === '_' || !$[jqName][options]) {
throw 'Unknown method: ' + options;
}
$[jqName][options].apply($[jqName], [this].concat(otherArgs));
var methodValue = $[jqName][options].apply($[jqName], [this].concat(otherArgs));
if (methodValue !== inst && methodValue !== undefined) {
returnValue = methodValue;
return false;
}
}
else {
$[jqName]._attach(this, options);
}
});
return returnValue;
};
},
/** Set default values for all subsequent instances.
@param options {object} The new default options.
@example $.plugin.setDefauls({name: value}) */
/** Set default options for all subsequent instances.
@param {object} options The new default options.
@example $.pluginName.setDefaults({name: value, ...}) */
setDefaults: function (options) {
$.extend(this.defaultOptions, options || {});
},
/** Determine whether a method is a getter and doesn't permit chaining.
@private
@param name {string} The method name.
@param otherArgs {any[]} Any other arguments for the method.
@return {boolean} True if this method is a getter, false otherwise. */
_isNotChained: function (name, otherArgs) {
if (name === 'option' && (otherArgs.length === 0 ||
(otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) {
return true;
}
return $.inArray(name, this._getters) > -1;
},
/** Initialise an element. Called internally only.
Adds an instance object as data named for the plugin.
@param elem {Element} The element to enhance.
@param options {object} Overriding settings. */
Override {@linkcode module:JQPlugin~_postAttach|_postAttach} for plugin-specific processing.
@private
@param {Element} elem The element to enhance.
@param {object} options Overriding settings. */
_attach: function (elem, options) {
elem = $(elem);
if (elem.hasClass(this._getMarker())) {
return;
}
elem.addClass(this._getMarker());
options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {});
options = $.extend(this.deepMerge, {}, this.defaultOptions, this._getMetadata(elem), options || {});
var inst = $.extend({ name: this.name, elem: elem, options: options }, this._instSettings(elem, options));
elem.data(this.name, inst); // Save instance against element
this._postAttach(elem, inst);
@@ -158,46 +188,57 @@
},
/** Retrieve additional instance settings.
Override this in a sub-class to provide extra settings.
@param elem {jQuery} The current jQuery element.
@param options {object} The instance options.
These are added directly to the instance object.
Default attributes of an instance object are shown as properties below:
@protected
@param {jQuery} elem The current jQuery element.
@param {object} options The instance options.
@return {object} Any extra instance values.
@property {Element} elem The element to which this instance applies.
@property {string} name The name of this plugin.
@property {object} options The accumulated options for this instance.
@example _instSettings: function(elem, options) {
return {nav: elem.find(options.navSelector)};
} */
return {nav: elem.find(options.navSelector)};
} */
_instSettings: function (elem, options) {
return {};
},
/** Plugin specific post initialisation.
Override this in a sub-class to perform extra activities.
@param elem {jQuery} The current jQuery element.
@param inst {object} The instance settings.
This is where you would implement your plugin's main functionality.
@protected
@param {jQuery} elem The current jQuery element.
@param {object} inst The instance settings.
@example _postAttach: function(elem, inst) {
elem.on('click.' + this.name, function() {
...
});
} */
elem.on('click.' + this.name, function() {
...
});
} */
_postAttach: function (elem, inst) {
},
/** Retrieve metadata configuration from the element.
Metadata is specified as an attribute:
<code>data-&lt;plugin name>="&lt;setting name>: '&lt;value>', ..."</code>.
Dates should be specified as strings in this format: 'new Date(y, m-1, d)'.
<code>data-&lt;pluginName>="&lt;option name>: '&lt;value>', ..."</code>.
Dates should be specified as strings in this format: <code>'new Date(y, m-1, d)'</code>.
@private
@param elem {jQuery} The source element.
@param {jQuery} elem The source element.
@return {object} The inline configuration or {}. */
_getMetadata: function (elem) {
try {
var data = elem.data(this.name.toLowerCase()) || '';
data = data.replace(/'/g, '"');
data = data.replace(/([a-zA-Z0-9]+):/g, function (match, group, i) {
data = data.replace(/(\\?)'/g, function (e, t) {
return t ? '\'' : '"';
}).replace(/([a-zA-Z0-9]+):/g, function (match, group, i) {
var count = data.substring(0, i).match(/"/g); // Handle embedded ':'
return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':');
});
}).replace(/\\:/g, ':');
data = $.parseJSON('{' + data + '}');
for (var name in data) {
var value = data[name];
if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) {
data[name] = eval(value);
for (var key in data) {
if (data.hasOwnProperty(key)) {
var value = data[key];
if (typeof value === 'string' && value.match(/^new Date\(([-0-9,\s]*)\)$/)) {
data[key] = eval(value); // jshint ignore:line
}
}
}
return data;
@@ -207,31 +248,37 @@
}
},
/** Retrieve the instance data for element.
@param elem {Element} The source element.
@return {object} The instance data or {}. */
@protected
@param {Element} elem The source element.
@return {object} The instance data or <code>{}</code> if none. */
_getInst: function (elem) {
return $(elem).data(this.name) || {};
},
/** Retrieve or reconfigure the settings for a plugin.
@param elem {Element} The source element.
@param name {object|string} The collection of new option values or the name of a single option.
@param [value] {any} The value for a single named option.
If new settings are provided they are applied to the instance options.
If an option name only is provided the value of that option is returned.
If no name or value is provided, all options are returned.
Override {@linkcode module:JQPlugin~_optionsChanged|_optionsChanged}
for plugin-specific processing when option values change.
@param {Element} elem The source element.
@param {object|string} [name] The collection of new option values or the name of a single option.
@param {any} [value] The value for a single named option.
@return {any|object} If retrieving a single value or all options.
@example $(selector).plugin('option', 'name', value)
$(selector).plugin('option', {name: value, ...})
var value = $(selector).plugin('option', 'name')
var options = $(selector).plugin('option') */
@example $(selector).plugin('option', 'name', value) // Set one option
$(selector).plugin('option', {name: value, ...}) // Set multiple options
var value = $(selector).plugin('option', 'name') // Get one option
var options = $(selector).plugin('option') // Get all options */
option: function (elem, name, value) {
elem = $(elem);
var inst = elem.data(this.name);
if (!name || (typeof name === 'string' && value == null)) {
var options = (inst || {}).options;
var options = name || {};
if (!name || (typeof name === 'string' && typeof value === 'undefined')) {
options = (inst || {}).options;
return (options && name ? options[name] : options);
}
if (!elem.hasClass(this._getMarker())) {
return;
}
var options = name || {};
if (typeof name === 'string') {
options = {};
options[name] = value;
@@ -242,19 +289,20 @@
/** Plugin specific options processing.
Old value available in <code>inst.options[name]</code>, new value in <code>options[name]</code>.
Override this in a sub-class to perform extra activities.
@param elem {jQuery} The current jQuery element.
@param inst {object} The instance settings.
@param options {object} The new options.
@protected
@param {jQuery} elem The current jQuery element.
@param {object} inst The instance settings.
@param {object} options The new options.
@example _optionsChanged: function(elem, inst, options) {
if (options.name != inst.options.name) {
elem.removeClass(inst.options.name).addClass(options.name);
}
} */
if (options.name != inst.options.name) {
elem.removeClass(inst.options.name).addClass(options.name);
}
} */
_optionsChanged: function (elem, inst, options) {
},
/** Remove all trace of the plugin.
Override <code>_preDestroy</code> for plugin-specific processing.
@param elem {Element} The source element.
Override {@linkcode module:JQPlugin~_preDestroy|_preDestroy} for plugin-specific processing.
@param {Element} elem The source element.
@example $(selector).plugin('destroy') */
destroy: function (elem) {
elem = $(elem);
@@ -265,19 +313,22 @@
elem.removeData(this.name).removeClass(this._getMarker());
},
/** Plugin specific pre destruction.
It is invoked as part of the {@linkcode module:JQPlugin~destroy|destroy} processing.
Override this in a sub-class to perform extra activities and undo everything that was
done in the <code>_postAttach</code> or <code>_optionsChanged</code> functions.
@param elem {jQuery} The current jQuery element.
@param inst {object} The instance settings.
done in the {@linkcode module:JQPlugin~_postAttach|_postAttach} or
{@linkcode module:JQPlugin~_optionsChanged|_optionsChanged} functions.
@protected
@param {jQuery} elem The current jQuery element.
@param {object} inst The instance settings.
@example _preDestroy: function(elem, inst) {
elem.off('.' + this.name);
} */
elem.off('.' + this.name);
} */
_preDestroy: function (elem, inst) {
}
});
/** Convert names from hyphenated to camel-case.
@private
@param value {string} The original hyphenated name.
@param {string} value The original hyphenated name.
@return {string} The camel-case version. */
function camelCase(name) {
return name.replace(/-([a-z])/g, function (match, group) {
@@ -285,18 +336,20 @@
});
}
/** Expose the plugin base.
@namespace "$.JQPlugin" */
@namespace $.JQPlugin */
$.JQPlugin = {
/** Create a new collection plugin.
@memberof "$.JQPlugin"
@param [superClass='JQPlugin'] {string} The name of the parent class to inherit from.
@param overrides {object} The property/function overrides for the new class.
@example $.JQPlugin.createPlugin({
name: 'tabs',
defaultOptions: {selectedClass: 'selected'},
_initSettings: function(elem, options) { return {...}; },
_postAttach: function(elem, inst) { ... }
}); */
@memberof $.JQPlugin
@param {string} [superClass='JQPlugin'] The name of the parent class to inherit from.
@param {object} overrides The property/function overrides for the new class.
See {@link module:JQPlugin|JQPlugin} for the base functionality.
@example $.JQPlugin.createPlugin({ // Define the plugin
name: 'tabs',
defaultOptions: {selectedClass: 'selected'},
_initSettings: function(elem, options) { return {...}; },
_postAttach: function(elem, inst) { ... }
});
$('selector').tabs(); // And instantiate it */
createPlugin: function (superClass, overrides) {
if (typeof superClass === 'object') {
overrides = superClass;
@@ -305,7 +358,7 @@
superClass = camelCase(superClass);
var className = camelCase(overrides.name);
JQClass.classes[className] = JQClass.classes[superClass].extend(overrides);
new JQClass.classes[className]();
new JQClass.classes[className](); // jshint ignore:line
}
};
})(jQuery);

View File

@@ -1 +1 @@
!function(){var t=!1;window.JQClass=function(){},JQClass.classes={},JQClass.extend=function e(n){function a(){!t&&this._init&&this._init.apply(this,arguments)}var s=this.prototype;t=!0;var i=new this;t=!1;for(var r in n)i[r]="function"==typeof n[r]&&"function"==typeof s[r]?function(t,e){return function(){var n=this._super;this._super=function(e){return s[t].apply(this,e||[])};var a=e.apply(this,arguments);return this._super=n,a}}(r,n[r]):n[r];return a.prototype=i,a.prototype.constructor=a,a.extend=e,a}}(),function($){function camelCase(t){return t.replace(/-([a-z])/g,function(t,e){return e.toUpperCase()})}JQClass.classes.JQPlugin=JQClass.extend({name:"plugin",defaultOptions:{},regionalOptions:{},_getters:[],_getMarker:function(){return"is-"+this.name},_init:function(){$.extend(this.defaultOptions,this.regionalOptions&&this.regionalOptions[""]||{});var t=camelCase(this.name);$[t]=this,$.fn[t]=function(e){var n=Array.prototype.slice.call(arguments,1);return $[t]._isNotChained(e,n)?$[t][e].apply($[t],[this[0]].concat(n)):this.each(function(){if("string"==typeof e){if("_"===e[0]||!$[t][e])throw"Unknown method: "+e;$[t][e].apply($[t],[this].concat(n))}else $[t]._attach(this,e)})}},setDefaults:function(t){$.extend(this.defaultOptions,t||{})},_isNotChained:function(t,e){return"option"===t&&(0===e.length||1===e.length&&"string"==typeof e[0])||$.inArray(t,this._getters)>-1},_attach:function(t,e){if(t=$(t),!t.hasClass(this._getMarker())){t.addClass(this._getMarker()),e=$.extend({},this.defaultOptions,this._getMetadata(t),e||{});var n=$.extend({name:this.name,elem:t,options:e},this._instSettings(t,e));t.data(this.name,n),this._postAttach(t,n),this.option(t,e)}},_instSettings:function(t,e){return{}},_postAttach:function(t,e){},_getMetadata:function(elem){try{var data=elem.data(this.name.toLowerCase())||"";data=data.replace(/'/g,'"'),data=data.replace(/([a-zA-Z0-9]+):/g,function(t,e,n){var a=data.substring(0,n).match(/"/g);return a&&a.length%2!==0?e+":":'"'+e+'":'}),data=$.parseJSON("{"+data+"}");for(var name in data){var value=data[name];"string"==typeof value&&value.match(/^new Date\((.*)\)$/)&&(data[name]=eval(value))}return data}catch(t){return{}}},_getInst:function(t){return $(t).data(this.name)||{}},option:function(t,e,n){t=$(t);var a=t.data(this.name);if(!e||"string"==typeof e&&null==n){var s=(a||{}).options;return s&&e?s[e]:s}if(t.hasClass(this._getMarker())){var s=e||{};"string"==typeof e&&(s={},s[e]=n),this._optionsChanged(t,a,s),$.extend(a.options,s)}},_optionsChanged:function(t,e,n){},destroy:function(t){t=$(t),t.hasClass(this._getMarker())&&(this._preDestroy(t,this._getInst(t)),t.removeData(this.name).removeClass(this._getMarker()))},_preDestroy:function(t,e){}}),$.JQPlugin={createPlugin:function(t,e){"object"==typeof t&&(e=t,t="JQPlugin"),t=camelCase(t);var n=camelCase(e.name);JQClass.classes[n]=JQClass.classes[t].extend(e),new JQClass.classes[n]}}}(jQuery);
!function(){"use strict";var t=!1;window.JQClass=function(){},JQClass.classes={},JQClass.extend=function e(n){function a(){!t&&this._init&&this._init.apply(this,arguments)}var s=this.prototype;t=!0;var i=new this;t=!1;for(var r in n)if("function"==typeof n[r]&&"function"==typeof s[r])i[r]=function(t,e){return function(){var n=this._super;this._super=function(e){return s[t].apply(this,e||[])};var a=e.apply(this,arguments);return this._super=n,a}}(r,n[r]);else if("object"==typeof n[r]&&"object"==typeof s[r]&&"defaultOptions"===r){var o,u=s[r],c=n[r],h={};for(o in u)h[o]=u[o];for(o in c)h[o]=c[o];i[r]=h}else i[r]=n[r];return a.prototype=i,a.prototype.constructor=a,a.extend=e,a}}(),function($){"use strict";function camelCase(t){return t.replace(/-([a-z])/g,function(t,e){return e.toUpperCase()})}JQClass.classes.JQPlugin=JQClass.extend({name:"plugin",defaultOptions:{},regionalOptions:{},deepMerge:!0,_getMarker:function(){return"is-"+this.name},_init:function(){$.extend(this.defaultOptions,this.regionalOptions&&this.regionalOptions[""]||{});var t=camelCase(this.name);$[t]=this,$.fn[t]=function(e){var n=Array.prototype.slice.call(arguments,1),a=this,s=this;return this.each(function(){if("string"==typeof e){if("_"===e[0]||!$[t][e])throw"Unknown method: "+e;var i=$[t][e].apply($[t],[this].concat(n));if(i!==a&&void 0!==i)return s=i,!1}else $[t]._attach(this,e)}),s}},setDefaults:function(t){$.extend(this.defaultOptions,t||{})},_attach:function(t,e){if(t=$(t),!t.hasClass(this._getMarker())){t.addClass(this._getMarker()),e=$.extend(this.deepMerge,{},this.defaultOptions,this._getMetadata(t),e||{});var n=$.extend({name:this.name,elem:t,options:e},this._instSettings(t,e));t.data(this.name,n),this._postAttach(t,n),this.option(t,e)}},_instSettings:function(t,e){return{}},_postAttach:function(t,e){},_getMetadata:function(elem){try{var data=elem.data(this.name.toLowerCase())||"";data=data.replace(/(\\?)'/g,function(t,e){return e?"'":'"'}).replace(/([a-zA-Z0-9]+):/g,function(t,e,n){var a=data.substring(0,n).match(/"/g);return a&&a.length%2!==0?e+":":'"'+e+'":'}).replace(/\\:/g,":"),data=$.parseJSON("{"+data+"}");for(var key in data)if(data.hasOwnProperty(key)){var value=data[key];"string"==typeof value&&value.match(/^new Date\(([-0-9,\s]*)\)$/)&&(data[key]=eval(value))}return data}catch(t){return{}}},_getInst:function(t){return $(t).data(this.name)||{}},option:function(t,e,n){t=$(t);var a=t.data(this.name),s=e||{};return!e||"string"==typeof e&&"undefined"==typeof n?(s=(a||{}).options,s&&e?s[e]:s):void(t.hasClass(this._getMarker())&&("string"==typeof e&&(s={},s[e]=n),this._optionsChanged(t,a,s),$.extend(a.options,s)))},_optionsChanged:function(t,e,n){},destroy:function(t){t=$(t),t.hasClass(this._getMarker())&&(this._preDestroy(t,this._getInst(t)),t.removeData(this.name).removeClass(this._getMarker()))},_preDestroy:function(t,e){}}),$.JQPlugin={createPlugin:function(t,e){"object"==typeof t&&(e=t,t="JQPlugin"),t=camelCase(t);var n=camelCase(e.name);JQClass.classes[n]=JQClass.classes[t].extend(e),new JQClass.classes[n]}}}(jQuery);