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.

508 lines
15 KiB

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