foundation.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. * Foundation Responsive Library
  3. * http://foundation.zurb.com
  4. * Copyright 2013, ZURB
  5. * Free to use under the MIT license.
  6. * http://www.opensource.org/licenses/mit-license.php
  7. */
  8. /*jslint unparam: true, browser: true, indent: 2 */
  9. // Accommodate running jQuery or Zepto in noConflict() mode by
  10. // using an anonymous function to redefine the $ shorthand name.
  11. // See http://docs.jquery.com/Using_jQuery_with_Other_Libraries
  12. // and http://zeptojs.com/
  13. var libFuncName = null;
  14. if (typeof jQuery === "undefined" &&
  15. typeof Zepto === "undefined" &&
  16. typeof $ === "function") {
  17. libFuncName = $;
  18. } else if (typeof jQuery === "function") {
  19. libFuncName = jQuery;
  20. } else if (typeof Zepto === "function") {
  21. libFuncName = Zepto;
  22. } else {
  23. throw new TypeError();
  24. }
  25. (function ($, window, document, undefined) {
  26. 'use strict';
  27. /*
  28. matchMedia() polyfill - Test a CSS media
  29. type/query in JS. Authors & copyright (c) 2012:
  30. Scott Jehl, Paul Irish, Nicholas Zakas.
  31. Dual MIT/BSD license
  32. https://github.com/paulirish/matchMedia.js
  33. */
  34. window.matchMedia = window.matchMedia || (function( doc, undefined ) {
  35. "use strict";
  36. var bool,
  37. docElem = doc.documentElement,
  38. refNode = docElem.firstElementChild || docElem.firstChild,
  39. // fakeBody required for <FF4 when executed in <head>
  40. fakeBody = doc.createElement( "body" ),
  41. div = doc.createElement( "div" );
  42. div.id = "mq-test-1";
  43. div.style.cssText = "position:absolute;top:-100em";
  44. fakeBody.style.background = "none";
  45. fakeBody.appendChild(div);
  46. return function(q){
  47. div.innerHTML = "&shy;<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";
  48. docElem.insertBefore( fakeBody, refNode );
  49. bool = div.offsetWidth === 42;
  50. docElem.removeChild( fakeBody );
  51. return {
  52. matches: bool,
  53. media: q
  54. };
  55. };
  56. }( document ));
  57. // add dusty browser stuff
  58. if (!Array.prototype.filter) {
  59. Array.prototype.filter = function(fun /*, thisp */) {
  60. "use strict";
  61. if (this == null) {
  62. throw new TypeError();
  63. }
  64. var t = Object(this),
  65. len = t.length >>> 0;
  66. if (typeof fun != "function") {
  67. return;
  68. }
  69. var res = [],
  70. thisp = arguments[1];
  71. for (var i = 0; i < len; i++) {
  72. if (i in t) {
  73. var val = t[i]; // in case fun mutates this
  74. if (fun && fun.call(thisp, val, i, t)) {
  75. res.push(val);
  76. }
  77. }
  78. }
  79. return res;
  80. }
  81. }
  82. if (!Function.prototype.bind) {
  83. Function.prototype.bind = function (oThis) {
  84. if (typeof this !== "function") {
  85. // closest thing possible to the ECMAScript 5 internal IsCallable function
  86. throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  87. }
  88. var aArgs = Array.prototype.slice.call(arguments, 1),
  89. fToBind = this,
  90. fNOP = function () {},
  91. fBound = function () {
  92. return fToBind.apply(this instanceof fNOP && oThis
  93. ? this
  94. : oThis,
  95. aArgs.concat(Array.prototype.slice.call(arguments)));
  96. };
  97. fNOP.prototype = this.prototype;
  98. fBound.prototype = new fNOP();
  99. return fBound;
  100. };
  101. }
  102. if (!Array.prototype.indexOf) {
  103. Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
  104. "use strict";
  105. if (this == null) {
  106. throw new TypeError();
  107. }
  108. var t = Object(this);
  109. var len = t.length >>> 0;
  110. if (len === 0) {
  111. return -1;
  112. }
  113. var n = 0;
  114. if (arguments.length > 1) {
  115. n = Number(arguments[1]);
  116. if (n != n) { // shortcut for verifying if it's NaN
  117. n = 0;
  118. } else if (n != 0 && n != Infinity && n != -Infinity) {
  119. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  120. }
  121. }
  122. if (n >= len) {
  123. return -1;
  124. }
  125. var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
  126. for (; k < len; k++) {
  127. if (k in t && t[k] === searchElement) {
  128. return k;
  129. }
  130. }
  131. return -1;
  132. }
  133. }
  134. // fake stop() for zepto.
  135. $.fn.stop = $.fn.stop || function() {
  136. return this;
  137. };
  138. window.Foundation = {
  139. name : 'Foundation',
  140. version : '4.2.0',
  141. cache : {},
  142. init : function (scope, libraries, method, options, response, /* internal */ nc) {
  143. var library_arr,
  144. args = [scope, method, options, response],
  145. responses = [],
  146. nc = nc || false;
  147. // disable library error catching,
  148. // used for development only
  149. if (nc) this.nc = nc;
  150. // check RTL
  151. this.rtl = /rtl/i.test($('html').attr('dir'));
  152. // set foundation global scope
  153. this.scope = scope || this.scope;
  154. if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) {
  155. if (/off/i.test(libraries)) return this.off();
  156. library_arr = libraries.split(' ');
  157. if (library_arr.length > 0) {
  158. for (var i = library_arr.length - 1; i >= 0; i--) {
  159. responses.push(this.init_lib(library_arr[i], args));
  160. }
  161. }
  162. } else {
  163. if (/reflow/i.test(libraries)) args[1] = 'reflow';
  164. for (var lib in this.libs) {
  165. responses.push(this.init_lib(lib, args));
  166. }
  167. }
  168. // if first argument is callback, add to args
  169. if (typeof libraries === 'function') {
  170. args.unshift(libraries);
  171. }
  172. return this.response_obj(responses, args);
  173. },
  174. response_obj : function (response_arr, args) {
  175. for (var i = 0, len = args.length; i < len; i++) {
  176. if (typeof args[i] === 'function') {
  177. return args[i]({
  178. errors: response_arr.filter(function (s) {
  179. if (typeof s === 'string') return s;
  180. })
  181. });
  182. }
  183. }
  184. return response_arr;
  185. },
  186. init_lib : function (lib, args) {
  187. return this.trap(function () {
  188. if (this.libs.hasOwnProperty(lib)) {
  189. this.patch(this.libs[lib]);
  190. return this.libs[lib].init.apply(this.libs[lib], args);
  191. }
  192. else {
  193. return function () {};
  194. }
  195. }.bind(this), lib);
  196. },
  197. trap : function (fun, lib) {
  198. if (!this.nc) {
  199. try {
  200. return fun();
  201. } catch (e) {
  202. return this.error({name: lib, message: 'could not be initialized', more: e.name + ' ' + e.message});
  203. }
  204. }
  205. return fun();
  206. },
  207. patch : function (lib) {
  208. this.fix_outer(lib);
  209. lib.scope = this.scope;
  210. lib.rtl = this.rtl;
  211. },
  212. inherit : function (scope, methods) {
  213. var methods_arr = methods.split(' ');
  214. for (var i = methods_arr.length - 1; i >= 0; i--) {
  215. if (this.lib_methods.hasOwnProperty(methods_arr[i])) {
  216. this.libs[scope.name][methods_arr[i]] = this.lib_methods[methods_arr[i]];
  217. }
  218. }
  219. },
  220. random_str : function (length) {
  221. var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');
  222. if (!length) {
  223. length = Math.floor(Math.random() * chars.length);
  224. }
  225. var str = '';
  226. for (var i = 0; i < length; i++) {
  227. str += chars[Math.floor(Math.random() * chars.length)];
  228. }
  229. return str;
  230. },
  231. libs : {},
  232. // methods that can be inherited in libraries
  233. lib_methods : {
  234. set_data : function (node, data) {
  235. // this.name references the name of the library calling this method
  236. var id = [this.name,+new Date(),Foundation.random_str(5)].join('-');
  237. Foundation.cache[id] = data;
  238. node.attr('data-' + this.name + '-id', id);
  239. return data;
  240. },
  241. get_data : function (node) {
  242. return Foundation.cache[node.attr('data-' + this.name + '-id')];
  243. },
  244. remove_data : function (node) {
  245. if (node) {
  246. delete Foundation.cache[node.attr('data-' + this.name + '-id')];
  247. node.attr('data-' + this.name + '-id', '');
  248. } else {
  249. $('[data-' + this.name + '-id]').each(function () {
  250. delete Foundation.cache[$(this).attr('data-' + this.name + '-id')];
  251. $(this).attr('data-' + this.name + '-id', '');
  252. });
  253. }
  254. },
  255. throttle : function(fun, delay) {
  256. var timer = null;
  257. return function () {
  258. var context = this, args = arguments;
  259. clearTimeout(timer);
  260. timer = setTimeout(function () {
  261. fun.apply(context, args);
  262. }, delay);
  263. };
  264. },
  265. // parses data-options attribute on nodes and turns
  266. // them into an object
  267. data_options : function (el) {
  268. var opts = {}, ii, p,
  269. opts_arr = (el.attr('data-options') || ':').split(';'),
  270. opts_len = opts_arr.length;
  271. function isNumber (o) {
  272. return ! isNaN (o-0) && o !== null && o !== "" && o !== false && o !== true;
  273. }
  274. function trim(str) {
  275. if (typeof str === 'string') return $.trim(str);
  276. return str;
  277. }
  278. // parse options
  279. for (ii = opts_len - 1; ii >= 0; ii--) {
  280. p = opts_arr[ii].split(':');
  281. if (/true/i.test(p[1])) p[1] = true;
  282. if (/false/i.test(p[1])) p[1] = false;
  283. if (isNumber(p[1])) p[1] = parseInt(p[1], 10);
  284. if (p.length === 2 && p[0].length > 0) {
  285. opts[trim(p[0])] = trim(p[1]);
  286. }
  287. }
  288. return opts;
  289. },
  290. delay : function (fun, delay) {
  291. return setTimeout(fun, delay);
  292. },
  293. // animated scrolling
  294. scrollTo : function (el, to, duration) {
  295. if (duration < 0) return;
  296. var difference = to - $(window).scrollTop();
  297. var perTick = difference / duration * 10;
  298. this.scrollToTimerCache = setTimeout(function() {
  299. if (!isNaN(parseInt(perTick, 10))) {
  300. window.scrollTo(0, $(window).scrollTop() + perTick);
  301. this.scrollTo(el, to, duration - 10);
  302. }
  303. }.bind(this), 10);
  304. },
  305. // not supported in core Zepto
  306. scrollLeft : function (el) {
  307. if (!el.length) return;
  308. return ('scrollLeft' in el[0]) ? el[0].scrollLeft : el[0].pageXOffset;
  309. },
  310. // test for empty object or array
  311. empty : function (obj) {
  312. if (obj.length && obj.length > 0) return false;
  313. if (obj.length && obj.length === 0) return true;
  314. for (var key in obj) {
  315. if (hasOwnProperty.call(obj, key)) return false;
  316. }
  317. return true;
  318. }
  319. },
  320. fix_outer : function (lib) {
  321. lib.outerHeight = function (el, bool) {
  322. if (typeof Zepto === 'function') {
  323. return el.height();
  324. }
  325. if (typeof bool !== 'undefined') {
  326. return el.outerHeight(bool);
  327. }
  328. return el.outerHeight();
  329. };
  330. lib.outerWidth = function (el) {
  331. if (typeof Zepto === 'function') {
  332. return el.width();
  333. }
  334. if (typeof bool !== 'undefined') {
  335. return el.outerWidth(bool);
  336. }
  337. return el.outerWidth();
  338. };
  339. },
  340. error : function (error) {
  341. return error.name + ' ' + error.message + '; ' + error.more;
  342. },
  343. // remove all foundation events.
  344. off: function () {
  345. $(this.scope).off('.fndtn');
  346. $(window).off('.fndtn');
  347. return true;
  348. },
  349. zj : function () {
  350. if (typeof Zepto !== 'undefined') {
  351. return Zepto;
  352. } else {
  353. return jQuery;
  354. }
  355. }()
  356. };
  357. $.fn.foundation = function () {
  358. var args = Array.prototype.slice.call(arguments, 0);
  359. return this.each(function () {
  360. Foundation.init.apply(Foundation, [this].concat(args));
  361. return this;
  362. });
  363. };
  364. }(libFuncName, this, this.document));