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.

280 lines
8.1 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. moduleSelector = $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.debug = 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,
  155. caption = settings.moduleName + ': ' + moduleSelector + '(' + $allModules.size() + ' elements)',
  156. totalExecutionTime = 0
  157. ;
  158. if(moduleSelector) {
  159. title += ' Performance (' + moduleSelector + ')';
  160. }
  161. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  162. console.groupCollapsed(title);
  163. if(console.table) {
  164. $.each(performance, function(index, data) {
  165. totalExecutionTime += data['Execution Time'];
  166. });
  167. console.table(performance);
  168. }
  169. else {
  170. $.each(performance, function(index, data) {
  171. totalExecutionTime += data['Execution Time'];
  172. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  173. });
  174. }
  175. console.log('Total Execution Time:', totalExecutionTime +'ms');
  176. console.groupEnd();
  177. performance = [];
  178. time = false;
  179. }
  180. }
  181. },
  182. invoke: function(query, passedArguments, context) {
  183. var
  184. maxDepth,
  185. found
  186. ;
  187. passedArguments = passedArguments || queryArguments;
  188. context = element || context;
  189. if(typeof query == 'string' && instance !== undefined) {
  190. query = query.split('.');
  191. maxDepth = query.length - 1;
  192. $.each(query, function(depth, value) {
  193. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  194. instance = instance[value];
  195. return true;
  196. }
  197. else if( instance[value] !== undefined ) {
  198. found = instance[value];
  199. return true;
  200. }
  201. module.error(error.method);
  202. return false;
  203. });
  204. }
  205. if ( $.isFunction( found ) ) {
  206. module.verbose('Executing invoked function', found);
  207. return found.apply(context, passedArguments);
  208. }
  209. return found || false;
  210. }
  211. };
  212. if(methodInvoked) {
  213. if(instance === undefined) {
  214. module.initialize();
  215. }
  216. invokedResponse = module.invoke(query);
  217. }
  218. else {
  219. if(instance !== undefined) {
  220. module.destroy();
  221. }
  222. module.initialize();
  223. }
  224. })
  225. ;
  226. return (invokedResponse)
  227. ? invokedResponse
  228. : this
  229. ;
  230. };
  231. $.fn.example.settings = {
  232. moduleName : 'Example Module',
  233. debug : true,
  234. verbose : false,
  235. performance : false,
  236. namespace : 'example',
  237. selector : {
  238. example : '.example'
  239. },
  240. error: {
  241. noText : 'The text you tried to display has not been defined.', method : 'The method you called is not defined.'
  242. },
  243. className : {
  244. disabled : 'disabled'
  245. },
  246. metadata: {
  247. notUsed: 'notUsed'
  248. },
  249. onChange : function() {},
  250. text: {
  251. hover : 'You are hovering me now',
  252. click : 'You clicked on me'
  253. }
  254. };
  255. })( jQuery, window , document );