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.

507 lines
15 KiB

9 years ago
10 years ago
6 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 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
9 years ago
10 years ago
9 years ago
  1. /*!
  2. * # Semantic UI 2.4.1 - Nag
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Released under the MIT license
  7. * http://opensource.org/licenses/MIT
  8. *
  9. */
  10. ;(function ($, window, document, undefined) {
  11. 'use strict';
  12. window = (typeof window != 'undefined' && window.Math == Math)
  13. ? window
  14. : (typeof self != 'undefined' && self.Math == Math)
  15. ? self
  16. : Function('return this')()
  17. ;
  18. $.fn.nag = function(parameters) {
  19. var
  20. $allModules = $(this),
  21. moduleSelector = $allModules.selector || '',
  22. time = new Date().getTime(),
  23. performance = [],
  24. query = arguments[0],
  25. methodInvoked = (typeof query == 'string'),
  26. queryArguments = [].slice.call(arguments, 1),
  27. returnedValue
  28. ;
  29. $allModules
  30. .each(function() {
  31. var
  32. settings = ( $.isPlainObject(parameters) )
  33. ? $.extend(true, {}, $.fn.nag.settings, parameters)
  34. : $.extend({}, $.fn.nag.settings),
  35. className = settings.className,
  36. selector = settings.selector,
  37. error = settings.error,
  38. namespace = settings.namespace,
  39. eventNamespace = '.' + namespace,
  40. moduleNamespace = namespace + '-module',
  41. $module = $(this),
  42. $close = $module.find(selector.close),
  43. $context = (settings.context)
  44. ? $(settings.context)
  45. : $('body'),
  46. element = this,
  47. instance = $module.data(moduleNamespace),
  48. moduleOffset,
  49. moduleHeight,
  50. contextWidth,
  51. contextHeight,
  52. contextOffset,
  53. yOffset,
  54. yPosition,
  55. timer,
  56. module,
  57. requestAnimationFrame = window.requestAnimationFrame
  58. || window.mozRequestAnimationFrame
  59. || window.webkitRequestAnimationFrame
  60. || window.msRequestAnimationFrame
  61. || function(callback) { setTimeout(callback, 0); }
  62. ;
  63. module = {
  64. initialize: function() {
  65. module.verbose('Initializing element');
  66. $module
  67. .on('click' + eventNamespace, selector.close, module.dismiss)
  68. .data(moduleNamespace, module)
  69. ;
  70. if(settings.detachable && $module.parent()[0] !== $context[0]) {
  71. $module
  72. .detach()
  73. .prependTo($context)
  74. ;
  75. }
  76. if(settings.displayTime > 0) {
  77. setTimeout(module.hide, settings.displayTime);
  78. }
  79. module.show();
  80. },
  81. destroy: function() {
  82. module.verbose('Destroying instance');
  83. $module
  84. .removeData(moduleNamespace)
  85. .off(eventNamespace)
  86. ;
  87. },
  88. show: function() {
  89. if( module.should.show() && !$module.is(':visible') ) {
  90. module.debug('Showing nag', settings.animation.show);
  91. if(settings.animation.show == 'fade') {
  92. $module
  93. .fadeIn(settings.duration, settings.easing)
  94. ;
  95. }
  96. else {
  97. $module
  98. .slideDown(settings.duration, settings.easing)
  99. ;
  100. }
  101. }
  102. },
  103. hide: function() {
  104. module.debug('Showing nag', settings.animation.hide);
  105. if(settings.animation.show == 'fade') {
  106. $module
  107. .fadeIn(settings.duration, settings.easing)
  108. ;
  109. }
  110. else {
  111. $module
  112. .slideUp(settings.duration, settings.easing)
  113. ;
  114. }
  115. },
  116. onHide: function() {
  117. module.debug('Removing nag', settings.animation.hide);
  118. $module.remove();
  119. if (settings.onHide) {
  120. settings.onHide();
  121. }
  122. },
  123. dismiss: function(event) {
  124. if(settings.storageMethod) {
  125. module.storage.set(settings.key, settings.value);
  126. }
  127. module.hide();
  128. event.stopImmediatePropagation();
  129. event.preventDefault();
  130. },
  131. should: {
  132. show: function() {
  133. if(settings.persist) {
  134. module.debug('Persistent nag is set, can show nag');
  135. return true;
  136. }
  137. if( module.storage.get(settings.key) != settings.value.toString() ) {
  138. module.debug('Stored value is not set, can show nag', module.storage.get(settings.key));
  139. return true;
  140. }
  141. module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key));
  142. return false;
  143. }
  144. },
  145. get: {
  146. storageOptions: function() {
  147. var
  148. options = {}
  149. ;
  150. if(settings.expires) {
  151. options.expires = settings.expires;
  152. }
  153. if(settings.domain) {
  154. options.domain = settings.domain;
  155. }
  156. if(settings.path) {
  157. options.path = settings.path;
  158. }
  159. return options;
  160. }
  161. },
  162. clear: function() {
  163. module.storage.remove(settings.key);
  164. },
  165. storage: {
  166. set: function(key, value) {
  167. var
  168. options = module.get.storageOptions()
  169. ;
  170. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  171. window.localStorage.setItem(key, value);
  172. module.debug('Value stored using local storage', key, value);
  173. }
  174. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  175. window.sessionStorage.setItem(key, value);
  176. module.debug('Value stored using session storage', key, value);
  177. }
  178. else if($.cookie !== undefined) {
  179. $.cookie(key, value, options);
  180. module.debug('Value stored using cookie', key, value, options);
  181. }
  182. else {
  183. module.error(error.noCookieStorage);
  184. return;
  185. }
  186. },
  187. get: function(key, value) {
  188. var
  189. storedValue
  190. ;
  191. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  192. storedValue = window.localStorage.getItem(key);
  193. }
  194. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  195. storedValue = window.sessionStorage.getItem(key);
  196. }
  197. // get by cookie
  198. else if($.cookie !== undefined) {
  199. storedValue = $.cookie(key);
  200. }
  201. else {
  202. module.error(error.noCookieStorage);
  203. }
  204. if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
  205. storedValue = undefined;
  206. }
  207. return storedValue;
  208. },
  209. remove: function(key) {
  210. var
  211. options = module.get.storageOptions()
  212. ;
  213. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  214. window.localStorage.removeItem(key);
  215. }
  216. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  217. window.sessionStorage.removeItem(key);
  218. }
  219. // store by cookie
  220. else if($.cookie !== undefined) {
  221. $.removeCookie(key, options);
  222. }
  223. else {
  224. module.error(error.noStorage);
  225. }
  226. }
  227. },
  228. setting: function(name, value) {
  229. module.debug('Changing setting', name, value);
  230. if( $.isPlainObject(name) ) {
  231. $.extend(true, settings, name);
  232. }
  233. else if(value !== undefined) {
  234. if($.isPlainObject(settings[name])) {
  235. $.extend(true, settings[name], value);
  236. }
  237. else {
  238. settings[name] = value;
  239. }
  240. }
  241. else {
  242. return settings[name];
  243. }
  244. },
  245. internal: function(name, value) {
  246. if( $.isPlainObject(name) ) {
  247. $.extend(true, module, name);
  248. }
  249. else if(value !== undefined) {
  250. module[name] = value;
  251. }
  252. else {
  253. return module[name];
  254. }
  255. },
  256. debug: function() {
  257. if(!settings.silent && settings.debug) {
  258. if(settings.performance) {
  259. module.performance.log(arguments);
  260. }
  261. else {
  262. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  263. module.debug.apply(console, arguments);
  264. }
  265. }
  266. },
  267. verbose: function() {
  268. if(!settings.silent && settings.verbose && settings.debug) {
  269. if(settings.performance) {
  270. module.performance.log(arguments);
  271. }
  272. else {
  273. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  274. module.verbose.apply(console, arguments);
  275. }
  276. }
  277. },
  278. error: function() {
  279. if(!settings.silent) {
  280. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  281. module.error.apply(console, arguments);
  282. }
  283. },
  284. performance: {
  285. log: function(message) {
  286. var
  287. currentTime,
  288. executionTime,
  289. previousTime
  290. ;
  291. if(settings.performance) {
  292. currentTime = new Date().getTime();
  293. previousTime = time || currentTime;
  294. executionTime = currentTime - previousTime;
  295. time = currentTime;
  296. performance.push({
  297. 'Name' : message[0],
  298. 'Arguments' : [].slice.call(message, 1) || '',
  299. 'Element' : element,
  300. 'Execution Time' : executionTime
  301. });
  302. }
  303. clearTimeout(module.performance.timer);
  304. module.performance.timer = setTimeout(module.performance.display, 500);
  305. },
  306. display: function() {
  307. var
  308. title = settings.name + ':',
  309. totalTime = 0
  310. ;
  311. time = false;
  312. clearTimeout(module.performance.timer);
  313. $.each(performance, function(index, data) {
  314. totalTime += data['Execution Time'];
  315. });
  316. title += ' ' + totalTime + 'ms';
  317. if(moduleSelector) {
  318. title += ' \'' + moduleSelector + '\'';
  319. }
  320. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  321. console.groupCollapsed(title);
  322. if(console.table) {
  323. console.table(performance);
  324. }
  325. else {
  326. $.each(performance, function(index, data) {
  327. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  328. });
  329. }
  330. console.groupEnd();
  331. }
  332. performance = [];
  333. }
  334. },
  335. invoke: function(query, passedArguments, context) {
  336. var
  337. object = instance,
  338. maxDepth,
  339. found,
  340. response
  341. ;
  342. passedArguments = passedArguments || queryArguments;
  343. context = element || context;
  344. if(typeof query == 'string' && object !== undefined) {
  345. query = query.split(/[\. ]/);
  346. maxDepth = query.length - 1;
  347. $.each(query, function(depth, value) {
  348. var camelCaseValue = (depth != maxDepth)
  349. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  350. : query
  351. ;
  352. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  353. object = object[camelCaseValue];
  354. }
  355. else if( object[camelCaseValue] !== undefined ) {
  356. found = object[camelCaseValue];
  357. return false;
  358. }
  359. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  360. object = object[value];
  361. }
  362. else if( object[value] !== undefined ) {
  363. found = object[value];
  364. return false;
  365. }
  366. else {
  367. module.error(error.method, query);
  368. return false;
  369. }
  370. });
  371. }
  372. if ( $.isFunction( found ) ) {
  373. response = found.apply(context, passedArguments);
  374. }
  375. else if(found !== undefined) {
  376. response = found;
  377. }
  378. if($.isArray(returnedValue)) {
  379. returnedValue.push(response);
  380. }
  381. else if(returnedValue !== undefined) {
  382. returnedValue = [returnedValue, response];
  383. }
  384. else if(response !== undefined) {
  385. returnedValue = response;
  386. }
  387. return found;
  388. }
  389. };
  390. if(methodInvoked) {
  391. if(instance === undefined) {
  392. module.initialize();
  393. }
  394. module.invoke(query);
  395. }
  396. else {
  397. if(instance !== undefined) {
  398. instance.invoke('destroy');
  399. }
  400. module.initialize();
  401. }
  402. })
  403. ;
  404. return (returnedValue !== undefined)
  405. ? returnedValue
  406. : this
  407. ;
  408. };
  409. $.fn.nag.settings = {
  410. name : 'Nag',
  411. silent : false,
  412. debug : false,
  413. verbose : false,
  414. performance : true,
  415. namespace : 'Nag',
  416. // allows cookie to be overridden
  417. persist : false,
  418. // set to zero to require manually dismissal, otherwise hides on its own
  419. displayTime : 0,
  420. animation : {
  421. show : 'slide',
  422. hide : 'slide'
  423. },
  424. context : false,
  425. detachable : false,
  426. expires : 30,
  427. domain : false,
  428. path : '/',
  429. // type of storage to use
  430. storageMethod : 'cookie',
  431. // value to store in dismissed localstorage/cookie
  432. key : 'nag',
  433. value : 'dismiss',
  434. error: {
  435. noCookieStorage : '$.cookie is not included. A storage solution is required.',
  436. noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state',
  437. method : 'The method you called is not defined.'
  438. },
  439. className : {
  440. bottom : 'bottom',
  441. fixed : 'fixed'
  442. },
  443. selector : {
  444. close : '.close.icon'
  445. },
  446. speed : 500,
  447. easing : 'easeOutQuad',
  448. onHide: function() {}
  449. };
  450. // Adds easing
  451. $.extend( $.easing, {
  452. easeOutQuad: function (x, t, b, c, d) {
  453. return -c *(t/=d)*(t-2) + b;
  454. }
  455. });
  456. })( jQuery, window, document );