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.

501 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
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 overriden
  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. })( jQuery, window, document );