You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
7.9 KiB

  1. ;(function ( $, window, document, undefined ) {
  2. $.fn.example = function(parameters) {
  3. var
  4. $allModules = $(this),
  5. settings = $.extend(true, {}, $.fn.example.settings, parameters),
  6. eventNamespace = '.' + settings.namespace,
  7. moduleNamespace = 'module-' + settings.namespace,
  8. selector = $allModules.selector || '',
  9. time = new Date().getTime(),
  10. performance = [],
  11. query = arguments[0],
  12. methodInvoked = (typeof query == 'string'),
  13. queryArguments = [].slice.call(arguments, 1),
  14. invokedResponse
  15. ;
  16. $allModules
  17. .each(function() {
  18. var
  19. $module = $(this),
  20. $text = $module.find(settings.selector.text),
  21. foo = false,
  22. instance = $module.data(moduleNamespace),
  23. element = this,
  24. namespace = settings.namespace,
  25. error = settings.error,
  26. className = settings.className,
  27. text = settings.text,
  28. module
  29. ;
  30. module = {
  31. initialize: function() {
  32. module.verbose('Initializing module for', element);
  33. $module
  34. .on('click' + eventNamespace, module.exampleBehavior)
  35. ;
  36. instance = module;
  37. $module
  38. .data(moduleNamespace, instance)
  39. ;
  40. },
  41. destroy: function() {
  42. module.verbose('Destroying previous module for', element);
  43. $module
  44. .removeData(moduleNamespace)
  45. .off(eventNamespace)
  46. ;
  47. },
  48. refresh: function() {
  49. module.verbose('Refreshing selector cache for', element);
  50. $module = $(element);
  51. $text = $(this).find(settings.selector.text);
  52. },
  53. event: {
  54. click: function(event) {
  55. module.verbose('Preventing default action');
  56. if( !$module.hasClass(className.disabled) ) {
  57. module.behavior();
  58. }
  59. event.preventDefault();
  60. }
  61. },
  62. behavior: function() {
  63. module.debug('Changing the text to a new value', text);
  64. if( !module.has.text() ) {
  65. module.set.text( text);
  66. }
  67. },
  68. has: {
  69. text: function(state) {
  70. module.verbose('Checking whether text state exists', state);
  71. if( text[state] === undefined ) {
  72. module.error(error.noText);
  73. return false;
  74. }
  75. return true;
  76. }
  77. },
  78. set: {
  79. text: function(state) {
  80. module.verbose('Setting text to new state', state);
  81. if( module.has.text(state) ) {
  82. $text
  83. .text( text[state] )
  84. ;
  85. settings.onChange();
  86. }
  87. }
  88. },
  89. setting: function(name, value) {
  90. if(value !== undefined) {
  91. if( $.isPlainObject(name) ) {
  92. $.extend(true, settings, name);
  93. }
  94. else {
  95. settings[name] = value;
  96. }
  97. }
  98. else {
  99. return settings[name];
  100. }
  101. },
  102. internal: function(name, value) {
  103. if(value !== undefined) {
  104. if( $.isPlainObject(name) ) {
  105. $.extend(true, module, name);
  106. }
  107. else {
  108. module[name] = value;
  109. }
  110. }
  111. else {
  112. return module[name];
  113. }
  114. },
  115. debug: function() {
  116. if(settings.debug) {
  117. module.performance.log(arguments[0]);
  118. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  119. }
  120. },
  121. verbose: function() {
  122. if(settings.verbose && settings.debug) {
  123. module.performance.log(arguments[0]);
  124. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  125. }
  126. },
  127. error: function() {
  128. if(console.log !== undefined) {
  129. module.error = Function.prototype.bind.call(console.log, console, settings.moduleName + ':');
  130. }
  131. },
  132. performance: {
  133. log: function(message) {
  134. var
  135. currentTime,
  136. executionTime,
  137. previousTime
  138. ;
  139. if(settings.performance) {
  140. currentTime = new Date().getTime();
  141. previousTime = time || currentTime,
  142. executionTime = currentTime - previousTime;
  143. time = currentTime;
  144. performance.push({
  145. 'Name' : message,
  146. 'Execution Time' : executionTime
  147. });
  148. clearTimeout(module.performance.timer);
  149. module.performance.timer = setTimeout(module.performance.display, 100);
  150. }
  151. },
  152. display: function() {
  153. var
  154. title = settings.moduleName + ' Performance (' + selector + ')',
  155. caption = settings.moduleName + ': ' + selector + '(' + $allModules.size() + ' elements)',
  156. totalExecutionTime = 0
  157. ;
  158. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  159. console.groupCollapsed(title );
  160. if(console.table) {
  161. $.each(performance, function(index, data) {
  162. totalExecutionTime += data['Execution Time'];
  163. });
  164. console.table(performance);
  165. }
  166. else {
  167. $.each(performance, function(index, data) {
  168. totalExecutionTime += data['Execution Time'];
  169. });
  170. }
  171. console.log('Total Execution Time:', totalExecutionTime);
  172. console.groupEnd();
  173. performance = [];
  174. time = false;
  175. }
  176. }
  177. },
  178. invoke: function(query, passedArguments, context) {
  179. var
  180. maxDepth,
  181. found
  182. ;
  183. passedArguments = passedArguments || queryArguments;
  184. context = element || context;
  185. if(typeof query == 'string' && instance !== undefined) {
  186. query = query.split('.');
  187. maxDepth = query.length - 1;
  188. $.each(query, function(depth, value) {
  189. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  190. instance = instance[value];
  191. return true;
  192. }
  193. else if( instance[value] !== undefined ) {
  194. found = instance[value];
  195. return true;
  196. }
  197. module.error(error.method);
  198. return false;
  199. });
  200. }
  201. if ( $.isFunction( found ) ) {
  202. module.verbose('Executing invoked function', found);
  203. return found.apply(context, passedArguments);
  204. }
  205. return found || false;
  206. }
  207. };
  208. if(methodInvoked) {
  209. if(instance === undefined) {
  210. module.initialize();
  211. }
  212. invokedResponse = module.invoke(query);
  213. }
  214. else {
  215. if(instance !== undefined) {
  216. module.destroy();
  217. }
  218. module.initialize();
  219. }
  220. })
  221. ;
  222. return (invokedResponse)
  223. ? invokedResponse
  224. : this
  225. ;
  226. };
  227. $.fn.example.settings = {
  228. moduleName : 'Example Module',
  229. debug : true,
  230. verbose : false,
  231. performance : false,
  232. namespace : 'example',
  233. selector : {
  234. example : '.example'
  235. },
  236. error: {
  237. noText : 'The text you tried to display has not been defined.', method : 'The method you called is not defined.'
  238. },
  239. className : {
  240. disabled : 'disabled'
  241. },
  242. metadata: {
  243. notUsed: 'notUsed'
  244. },
  245. onChange : function() {},
  246. text: {
  247. hover : 'You are hovering me now',
  248. click : 'You clicked on me'
  249. }
  250. };
  251. })( jQuery, window , document );