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.

486 lines
14 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*
  2. * # Semantic - Site
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2014 Contributor
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. $.site = $.fn.site = function(parameters) {
  13. var
  14. time = new Date().getTime(),
  15. performance = [],
  16. query = arguments[0],
  17. methodInvoked = (typeof query == 'string'),
  18. queryArguments = [].slice.call(arguments, 1),
  19. settings = ( $.isPlainObject(parameters) )
  20. ? $.extend(true, {}, $.site.settings, parameters)
  21. : $.extend({}, $.site.settings),
  22. namespace = settings.namespace,
  23. error = settings.error,
  24. eventNamespace = '.' + namespace,
  25. moduleNamespace = 'module-' + namespace,
  26. $document = $(document),
  27. $module = $document,
  28. element = this,
  29. instance = $module.data(moduleNamespace),
  30. module,
  31. returnedValue
  32. ;
  33. module = {
  34. initialize: function() {
  35. module.instantiate();
  36. },
  37. instantiate: function() {
  38. module.verbose('Storing instance of site', module);
  39. instance = module;
  40. $module
  41. .data(moduleNamespace, module)
  42. ;
  43. },
  44. normalize: function() {
  45. module.fix.console();
  46. module.fix.requestAnimationFrame();
  47. },
  48. fix: {
  49. console: function() {
  50. module.debug('Normalizing window.console');
  51. if (console === undefined || console.log === undefined) {
  52. module.verbose('Console not available, normalizing events');
  53. module.disable.console();
  54. }
  55. if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
  56. module.verbose('Console group not available, normalizing events');
  57. window.console.group = function() {};
  58. window.console.groupEnd = function() {};
  59. window.console.groupCollapsed = function() {};
  60. }
  61. if (typeof console.markTimeline == 'undefined') {
  62. module.verbose('Mark timeline not available, normalizing events');
  63. window.console.markTimeline = function() {};
  64. }
  65. },
  66. consoleClear: function() {
  67. module.debug('Disabling programmatic console clearing');
  68. window.console.clear = function() {};
  69. },
  70. requestAnimationFrame: function() {
  71. module.debug('Normalizing requestAnimationFrame');
  72. if(window.requestAnimationFrame === undefined) {
  73. module.debug('RequestAnimationFrame not available, normailizing event');
  74. window.requestAnimationFrame = window.requestAnimationFrame
  75. || window.mozRequestAnimationFrame
  76. || window.webkitRequestAnimationFrame
  77. || window.msRequestAnimationFrame
  78. || function(callback) { setTimeout(callback, 0); }
  79. ;
  80. }
  81. }
  82. },
  83. moduleExists: function(name) {
  84. return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
  85. },
  86. enabled: {
  87. modules: function(modules) {
  88. var
  89. enabledModules = []
  90. ;
  91. modules = modules || settings.modules;
  92. $.each(modules, function(index, name) {
  93. if(module.moduleExists(name)) {
  94. enabledModules.push(name);
  95. }
  96. });
  97. return enabledModules;
  98. }
  99. },
  100. disabled: {
  101. modules: function(modules) {
  102. var
  103. disabledModules = []
  104. ;
  105. modules = modules || settings.modules;
  106. $.each(modules, function(index, name) {
  107. if(!module.moduleExists(name)) {
  108. disabledModules.push(name);
  109. }
  110. });
  111. return disabledModules;
  112. }
  113. },
  114. change: {
  115. setting: function(setting, value, modules, modifyExisting) {
  116. modules = (typeof modules === 'string')
  117. ? (modules === 'all')
  118. ? settings.modules
  119. : [modules]
  120. : modules || settings.modules
  121. ;
  122. modifyExisting = (modifyExisting !== undefined)
  123. ? modifyExisting
  124. : true
  125. ;
  126. $.each(modules, function(index, name) {
  127. var
  128. namespace = (module.moduleExists(name))
  129. ? $.fn[name].settings.namespace || false
  130. : true,
  131. $existingModules
  132. ;
  133. if(module.moduleExists(name)) {
  134. module.verbose('Changing default setting', setting, value, name);
  135. $.fn[name].settings[setting] = value;
  136. if(modifyExisting && namespace) {
  137. $existingModules = $(':data(module-' + namespace + ')');
  138. if($existingModules.size() > 0) {
  139. module.verbose('Modifying existing settings', $existingModules);
  140. $existingModules[name]('setting', setting, value);
  141. }
  142. }
  143. }
  144. });
  145. },
  146. settings: function(newSettings, modules, modifyExisting) {
  147. modules = (typeof modules === 'string')
  148. ? [modules]
  149. : modules || settings.modules
  150. ;
  151. modifyExisting = (modifyExisting !== undefined)
  152. ? modifyExisting
  153. : true
  154. ;
  155. $.each(modules, function(index, name) {
  156. var
  157. $existingModules
  158. ;
  159. if(module.moduleExists(name)) {
  160. module.verbose('Changing default setting', newSettings, name);
  161. $.extend(true, $.fn[name].settings, newSettings);
  162. if(modifyExisting && namespace) {
  163. $existingModules = $(':data(module-' + namespace + ')');
  164. if($existingModules.size() > 0) {
  165. module.verbose('Modifying existing settings', $existingModules);
  166. $existingModules[name]('setting', newSettings);
  167. }
  168. }
  169. }
  170. });
  171. }
  172. },
  173. enable: {
  174. console: function() {
  175. module.console(true);
  176. },
  177. debug: function(modules, modifyExisting) {
  178. modules = modules || settings.modules;
  179. module.debug('Enabling debug for modules', modules);
  180. module.change.setting('debug', true, modules, modifyExisting);
  181. },
  182. verbose: function(modules, modifyExisting) {
  183. modules = modules || settings.modules;
  184. module.debug('Enabling verbose debug for modules', modules);
  185. module.change.setting('verbose', true, modules, modifyExisting);
  186. }
  187. },
  188. disable: {
  189. console: function() {
  190. module.console(false);
  191. },
  192. debug: function(modules, modifyExisting) {
  193. modules = modules || settings.modules;
  194. module.debug('Disabling debug for modules', modules);
  195. module.change.setting('debug', false, modules, modifyExisting);
  196. },
  197. verbose: function(modules, modifyExisting) {
  198. modules = modules || settings.modules;
  199. module.debug('Disabling verbose debug for modules', modules);
  200. module.change.setting('verbose', false, modules, modifyExisting);
  201. }
  202. },
  203. console: function(enable) {
  204. if(enable) {
  205. if(instance.cache.console === undefined) {
  206. module.error(error.console);
  207. return;
  208. }
  209. module.debug('Restoring console function');
  210. window.console = instance.cache.console;
  211. }
  212. else {
  213. module.debug('Disabling console function');
  214. instance.cache.console = window.console;
  215. window.console = {
  216. clear : function(){},
  217. error : function(){},
  218. group : function(){},
  219. groupCollapsed : function(){},
  220. groupEnd : function(){},
  221. info : function(){},
  222. log : function(){},
  223. markTimeline : function(){},
  224. warn : function(){}
  225. };
  226. }
  227. },
  228. destroy: function() {
  229. module.verbose('Destroying previous site for', $module);
  230. $module
  231. .removeData(moduleNamespace)
  232. ;
  233. },
  234. cache: {},
  235. setting: function(name, value) {
  236. if( $.isPlainObject(name) ) {
  237. $.extend(true, settings, name);
  238. }
  239. else if(value !== undefined) {
  240. settings[name] = value;
  241. }
  242. else {
  243. return settings[name];
  244. }
  245. },
  246. internal: function(name, value) {
  247. if( $.isPlainObject(name) ) {
  248. $.extend(true, module, name);
  249. }
  250. else if(value !== undefined) {
  251. module[name] = value;
  252. }
  253. else {
  254. return module[name];
  255. }
  256. },
  257. debug: function() {
  258. if(settings.debug) {
  259. if(settings.performance) {
  260. module.performance.log(arguments);
  261. }
  262. else {
  263. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  264. module.debug.apply(console, arguments);
  265. }
  266. }
  267. },
  268. verbose: function() {
  269. if(settings.verbose && settings.debug) {
  270. if(settings.performance) {
  271. module.performance.log(arguments);
  272. }
  273. else {
  274. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  275. module.verbose.apply(console, arguments);
  276. }
  277. }
  278. },
  279. error: function() {
  280. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  281. module.error.apply(console, arguments);
  282. },
  283. performance: {
  284. log: function(message) {
  285. var
  286. currentTime,
  287. executionTime,
  288. previousTime
  289. ;
  290. if(settings.performance) {
  291. currentTime = new Date().getTime();
  292. previousTime = time || currentTime;
  293. executionTime = currentTime - previousTime;
  294. time = currentTime;
  295. performance.push({
  296. 'Element' : element,
  297. 'Name' : message[0],
  298. 'Arguments' : [].slice.call(message, 1) || '',
  299. 'Execution Time' : executionTime
  300. });
  301. }
  302. clearTimeout(module.performance.timer);
  303. module.performance.timer = setTimeout(module.performance.display, 100);
  304. },
  305. display: function() {
  306. var
  307. title = settings.name + ':',
  308. totalTime = 0
  309. ;
  310. time = false;
  311. clearTimeout(module.performance.timer);
  312. $.each(performance, function(index, data) {
  313. totalTime += data['Execution Time'];
  314. });
  315. title += ' ' + totalTime + 'ms';
  316. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  317. console.groupCollapsed(title);
  318. if(console.table) {
  319. console.table(performance);
  320. }
  321. else {
  322. $.each(performance, function(index, data) {
  323. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  324. });
  325. }
  326. console.groupEnd();
  327. }
  328. performance = [];
  329. }
  330. },
  331. invoke: function(query, passedArguments, context) {
  332. var
  333. object = instance,
  334. maxDepth,
  335. found,
  336. response
  337. ;
  338. passedArguments = passedArguments || queryArguments;
  339. context = element || context;
  340. if(typeof query == 'string' && object !== undefined) {
  341. query = query.split(/[\. ]/);
  342. maxDepth = query.length - 1;
  343. $.each(query, function(depth, value) {
  344. var camelCaseValue = (depth != maxDepth)
  345. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  346. : query
  347. ;
  348. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  349. object = object[camelCaseValue];
  350. }
  351. else if( object[camelCaseValue] !== undefined ) {
  352. found = object[camelCaseValue];
  353. return false;
  354. }
  355. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  356. object = object[value];
  357. }
  358. else if( object[value] !== undefined ) {
  359. found = object[value];
  360. return false;
  361. }
  362. else {
  363. module.error(error.method, query);
  364. return false;
  365. }
  366. });
  367. }
  368. if ( $.isFunction( found ) ) {
  369. response = found.apply(context, passedArguments);
  370. }
  371. else if(found !== undefined) {
  372. response = found;
  373. }
  374. if($.isArray(returnedValue)) {
  375. returnedValue.push(response);
  376. }
  377. else if(returnedValue !== undefined) {
  378. returnedValue = [returnedValue, response];
  379. }
  380. else if(response !== undefined) {
  381. returnedValue = response;
  382. }
  383. return found;
  384. }
  385. };
  386. if(methodInvoked) {
  387. if(instance === undefined) {
  388. module.initialize();
  389. }
  390. module.invoke(query);
  391. }
  392. else {
  393. if(instance !== undefined) {
  394. module.destroy();
  395. }
  396. module.initialize();
  397. }
  398. return (returnedValue !== undefined)
  399. ? returnedValue
  400. : this
  401. ;
  402. };
  403. $.site.settings = {
  404. name : 'Site',
  405. namespace : 'site',
  406. error : {
  407. console : 'Console cannot be restored, most likely it was overwritten outside of module',
  408. method : 'The method you called is not defined.'
  409. },
  410. debug : false,
  411. verbose : true,
  412. performance : true,
  413. modules: [
  414. 'accordion',
  415. 'api',
  416. 'checkbox',
  417. 'dimmer',
  418. 'dropdown',
  419. 'form',
  420. 'modal',
  421. 'nag',
  422. 'popup',
  423. 'rating',
  424. 'shape',
  425. 'sidebar',
  426. 'state',
  427. 'sticky',
  428. 'tab',
  429. 'transition',
  430. 'video',
  431. 'visit',
  432. 'visibility'
  433. ],
  434. siteNamespace : 'site',
  435. namespaceStub : {
  436. cache : {},
  437. config : {},
  438. sections : {},
  439. section : {},
  440. utilities : {}
  441. }
  442. };
  443. // allows for selection of elements with data attributes
  444. $.extend($.expr[ ":" ], {
  445. data: ($.expr.createPseudo)
  446. ? $.expr.createPseudo(function(dataName) {
  447. return function(elem) {
  448. return !!$.data(elem, dataName);
  449. };
  450. })
  451. : function(elem, i, match) {
  452. // support: jQuery < 1.8
  453. return !!$.data(elem, match[ 3 ]);
  454. }
  455. });
  456. })( jQuery, window , document );