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.

340 lines
9.4 KiB

11 years ago
  1. /* ******************************
  2. Semantic Module: Dropdown
  3. Author: Jack Lukic
  4. Notes: First Commit May 25, 2013
  5. ****************************** */
  6. ;(function ( $, window, document, undefined ) {
  7. $.fn.sidebar = function(parameters) {
  8. var
  9. $allModules = $(this),
  10. settings = ( $.isPlainObject(parameters) )
  11. ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
  12. : $.fn.sidebar.settings,
  13. className = settings.className,
  14. namespace = settings.namespace,
  15. error = settings.error,
  16. eventNamespace = '.' + namespace,
  17. moduleNamespace = 'module-' + namespace,
  18. moduleSelector = $allModules.selector || '',
  19. time = new Date().getTime(),
  20. performance = [],
  21. query = arguments[0],
  22. methodInvoked = (typeof query == 'string'),
  23. queryArguments = [].slice.call(arguments, 1),
  24. invokedResponse
  25. ;
  26. $allModules
  27. .each(function() {
  28. var
  29. $body = $('body'),
  30. $module = $(this),
  31. element = this,
  32. instance = $module.data(moduleNamespace),
  33. module
  34. ;
  35. module = {
  36. initialize: function() {
  37. module.debug('Initializing sidebar', $module);
  38. module.instantiate();
  39. },
  40. instantiate: function() {
  41. module.verbose('Storing instance of module', module);
  42. $module
  43. .data(moduleNamespace, module)
  44. ;
  45. },
  46. destroy: function() {
  47. module.verbose('Destroying previous module for', $module);
  48. $module
  49. .off(eventNamespace)
  50. .removeData(moduleNamespace)
  51. ;
  52. },
  53. attach: {
  54. events: function(selector, event) {
  55. var
  56. $toggle = $(selector)
  57. ;
  58. event = $.isFunction(module[event])
  59. ? module[event]
  60. : module.toggle
  61. ;
  62. if($toggle.size() > 0) {
  63. module.debug('Attaching sidebar events to element', selector, event);
  64. $toggle
  65. .on('click' + eventNamespace, event)
  66. ;
  67. }
  68. else {
  69. module.error(error.notFound);
  70. }
  71. }
  72. },
  73. show: function() {
  74. if(module.is.closed()) {
  75. module.debug('Showing sidebar');
  76. $body
  77. .animate(module.get.bodyCSS(), settings.duration, settings.onShow)
  78. ;
  79. $module
  80. .addClass(className.open)
  81. ;
  82. }
  83. },
  84. hide: function() {
  85. if(module.is.open()) {
  86. $module
  87. .removeClass(className.open)
  88. ;
  89. }
  90. },
  91. toggle: function() {
  92. if(module.is.open()) {
  93. module.close();
  94. }
  95. else {
  96. module.open();
  97. }
  98. },
  99. get: {
  100. bodyCSS: function() {
  101. }
  102. },
  103. is: {
  104. open: function() {
  105. return $module.is(':visible');
  106. },
  107. closed: function() {
  108. return $module.is(':not(:visible)');
  109. }
  110. },
  111. setting: function(name, value) {
  112. if(value !== undefined) {
  113. if( $.isPlainObject(name) ) {
  114. $.extend(true, settings, name);
  115. }
  116. else {
  117. settings[name] = value;
  118. }
  119. }
  120. else {
  121. return settings[name];
  122. }
  123. },
  124. internal: function(name, value) {
  125. if(value !== undefined) {
  126. if( $.isPlainObject(name) ) {
  127. $.extend(true, module, name);
  128. }
  129. else {
  130. module[name] = value;
  131. }
  132. }
  133. else {
  134. return module[name];
  135. }
  136. },
  137. debug: function() {
  138. if(settings.debug) {
  139. if(settings.performance) {
  140. module.performance.log(arguments);
  141. }
  142. else {
  143. module.debug = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  144. module.debug.apply(console, arguments);
  145. }
  146. }
  147. },
  148. verbose: function() {
  149. if(settings.verbose && settings.debug) {
  150. if(settings.performance) {
  151. module.performance.log(arguments);
  152. }
  153. else {
  154. module.verbose = Function.prototype.bind.call(console.info, console, settings.moduleName + ':');
  155. module.verbose.apply(console, arguments);
  156. }
  157. }
  158. },
  159. error: function() {
  160. module.error = Function.prototype.bind.call(console.error, console, settings.moduleName + ':');
  161. module.error.apply(console, arguments);
  162. },
  163. performance: {
  164. log: function(message) {
  165. var
  166. currentTime,
  167. executionTime,
  168. previousTime
  169. ;
  170. if(settings.performance) {
  171. currentTime = new Date().getTime();
  172. previousTime = time || currentTime;
  173. executionTime = currentTime - previousTime;
  174. time = currentTime;
  175. performance.push({
  176. 'Element' : element,
  177. 'Name' : message[0],
  178. 'Arguments' : [].slice.call(message, 1) || '',
  179. 'Execution Time' : executionTime
  180. });
  181. }
  182. clearTimeout(module.performance.timer);
  183. module.performance.timer = setTimeout(module.performance.display, 100);
  184. },
  185. display: function() {
  186. var
  187. title = settings.moduleName + ':',
  188. totalTime = 0
  189. ;
  190. time = false;
  191. clearTimeout(module.performance.timer);
  192. $.each(performance, function(index, data) {
  193. totalTime += data['Execution Time'];
  194. });
  195. title += ' ' + totalTime + 'ms';
  196. if(moduleSelector) {
  197. title += ' \'' + moduleSelector + '\'';
  198. }
  199. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  200. console.groupCollapsed(title);
  201. if(console.table) {
  202. console.table(performance);
  203. }
  204. else {
  205. $.each(performance, function(index, data) {
  206. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  207. });
  208. }
  209. console.groupEnd();
  210. }
  211. performance = [];
  212. }
  213. },
  214. invoke: function(query, passedArguments, context) {
  215. var
  216. maxDepth,
  217. found,
  218. response
  219. ;
  220. passedArguments = passedArguments || queryArguments;
  221. context = element || context;
  222. if(typeof query == 'string' && instance !== undefined) {
  223. query = query.split(/[\. ]/);
  224. maxDepth = query.length - 1;
  225. $.each(query, function(depth, value) {
  226. var camelCaseValue = (depth != maxDepth)
  227. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  228. : query
  229. ;
  230. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  231. instance = instance[value];
  232. }
  233. else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
  234. instance = instance[camelCaseValue];
  235. }
  236. else if( instance[value] !== undefined ) {
  237. found = instance[value];
  238. return false;
  239. }
  240. else if( instance[camelCaseValue] !== undefined ) {
  241. found = instance[camelCaseValue];
  242. return false;
  243. }
  244. else {
  245. module.error(error.method);
  246. return false;
  247. }
  248. });
  249. }
  250. if ( $.isFunction( found ) ) {
  251. response = found.apply(context, passedArguments);
  252. }
  253. else if(found !== undefined) {
  254. response = found;
  255. }
  256. if($.isArray(invokedResponse)) {
  257. invokedResponse.push(response);
  258. }
  259. else if(typeof invokedResponse == 'string') {
  260. invokedResponse = [invokedResponse, response];
  261. }
  262. else if(response !== undefined) {
  263. invokedResponse = response;
  264. }
  265. return found;
  266. }
  267. };
  268. if(methodInvoked) {
  269. if(instance === undefined) {
  270. module.initialize();
  271. }
  272. module.invoke(query);
  273. }
  274. else {
  275. if(instance !== undefined) {
  276. module.destroy();
  277. }
  278. module.initialize();
  279. }
  280. })
  281. ;
  282. return (invokedResponse !== undefined)
  283. ? invokedResponse
  284. : this
  285. ;
  286. };
  287. $.fn.sidebar.settings = {
  288. moduleName : 'Sidebar',
  289. namespace : 'sidebar',
  290. verbose : true,
  291. debug : true,
  292. performance : true,
  293. side : 'left',
  294. duration : 500,
  295. onChange : function(){},
  296. onShow : function(){},
  297. onHide : function(){},
  298. className: {
  299. open: 'active'
  300. },
  301. error : {
  302. method : 'The method you called is not defined.',
  303. notFound : 'There were no elements that matched the specified selector'
  304. }
  305. };
  306. })( jQuery, window , document );