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.

440 lines
12 KiB

6 years ago
  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.3.1',
  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. } else {
  192. return function () {};
  193. }
  194. }.bind(this), lib);
  195. },
  196. trap : function (fun, lib) {
  197. if (!this.nc) {
  198. try {
  199. return fun();
  200. } catch (e) {
  201. return this.error({name: lib, message: 'could not be initialized', more: e.name + ' ' + e.message});
  202. }
  203. }
  204. return fun();
  205. },
  206. patch : function (lib) {
  207. this.fix_outer(lib);
  208. lib.scope = this.scope;
  209. lib.rtl = this.rtl;
  210. },
  211. inherit : function (scope, methods) {
  212. var methods_arr = methods.split(' ');
  213. for (var i = methods_arr.length - 1; i >= 0; i--) {
  214. if (this.lib_methods.hasOwnProperty(methods_arr[i])) {
  215. this.libs[scope.name][methods_arr[i]] = this.lib_methods[methods_arr[i]];
  216. }
  217. }
  218. },
  219. random_str : function (length) {
  220. var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  221. if (!length) {
  222. length = Math.floor(Math.random() * chars.length);
  223. }
  224. var str = '';
  225. for (var i = 0; i < length; i++) {
  226. str += chars[Math.floor(Math.random() * chars.length)];
  227. }
  228. return str;
  229. },
  230. libs : {},
  231. // methods that can be inherited in libraries
  232. lib_methods : {
  233. set_data : function (node, data) {
  234. // this.name references the name of the library calling this method
  235. var id = [this.name,+new Date(),Foundation.random_str(5)].join('-');
  236. Foundation.cache[id] = data;
  237. node.attr('data-' + this.name + '-id', id);
  238. return data;
  239. },
  240. get_data : function (node) {
  241. return Foundation.cache[node.attr('data-' + this.name + '-id')];
  242. },
  243. remove_data : function (node) {
  244. if (node) {
  245. delete Foundation.cache[node.attr('data-' + this.name + '-id')];
  246. node.attr('data-' + this.name + '-id', '');
  247. } else {
  248. $('[data-' + this.name + '-id]').each(function () {
  249. delete Foundation.cache[$(this).attr('data-' + this.name + '-id')];
  250. $(this).attr('data-' + this.name + '-id', '');
  251. });
  252. }
  253. },
  254. throttle : function(fun, delay) {
  255. var timer = null;
  256. return function () {
  257. var context = this, args = arguments;
  258. clearTimeout(timer);
  259. timer = setTimeout(function () {
  260. fun.apply(context, args);
  261. }, delay);
  262. };
  263. },
  264. // parses data-options attribute on nodes and turns
  265. // them into an object
  266. data_options : function (el) {
  267. var opts = {}, ii, p,
  268. opts_arr = (el.attr('data-options') || ':').split(';'),
  269. opts_len = opts_arr.length;
  270. function isNumber (o) {
  271. return ! isNaN (o-0) && o !== null && o !== "" && o !== false && o !== true;
  272. }
  273. function trim(str) {
  274. if (typeof str === 'string') return $.trim(str);
  275. return str;
  276. }
  277. // parse options
  278. for (ii = opts_len - 1; ii >= 0; ii--) {
  279. p = opts_arr[ii].split(':');
  280. if (/true/i.test(p[1])) p[1] = true;
  281. if (/false/i.test(p[1])) p[1] = false;
  282. if (isNumber(p[1])) p[1] = parseInt(p[1], 10);
  283. if (p.length === 2 && p[0].length > 0) {
  284. opts[trim(p[0])] = trim(p[1]);
  285. }
  286. }
  287. return opts;
  288. },
  289. delay : function (fun, delay) {
  290. return setTimeout(fun, delay);
  291. },
  292. // animated scrolling
  293. scrollTo : function (el, to, duration) {
  294. if (duration < 0) return;
  295. var difference = to - $(window).scrollTop();
  296. var perTick = difference / duration * 10;
  297. this.scrollToTimerCache = setTimeout(function() {
  298. if (!isNaN(parseInt(perTick, 10))) {
  299. window.scrollTo(0, $(window).scrollTop() + perTick);
  300. this.scrollTo(el, to, duration - 10);
  301. }
  302. }.bind(this), 10);
  303. },
  304. // not supported in core Zepto
  305. scrollLeft : function (el) {
  306. if (!el.length) return;
  307. return ('scrollLeft' in el[0]) ? el[0].scrollLeft : el[0].pageXOffset;
  308. },
  309. // test for empty object or array
  310. empty : function (obj) {
  311. if (obj.length && obj.length > 0) return false;
  312. if (obj.length && obj.length === 0) return true;
  313. for (var key in obj) {
  314. if (hasOwnProperty.call(obj, key)) return false;
  315. }
  316. return true;
  317. }
  318. },
  319. fix_outer : function (lib) {
  320. lib.outerHeight = function (el, bool) {
  321. if (typeof Zepto === 'function') {
  322. return el.height();
  323. }
  324. if (typeof bool !== 'undefined') {
  325. return el.outerHeight(bool);
  326. }
  327. return el.outerHeight();
  328. };
  329. lib.outerWidth = function (el, bool) {
  330. if (typeof Zepto === 'function') {
  331. return el.width();
  332. }
  333. if (typeof bool !== 'undefined') {
  334. return el.outerWidth(bool);
  335. }
  336. return el.outerWidth();
  337. };
  338. },
  339. error : function (error) {
  340. return error.name + ' ' + error.message + '; ' + error.more;
  341. },
  342. // remove all foundation events.
  343. off: function () {
  344. $(this.scope).off('.fndtn');
  345. $(window).off('.fndtn');
  346. return true;
  347. },
  348. zj : $
  349. };
  350. $.fn.foundation = function () {
  351. var args = Array.prototype.slice.call(arguments, 0);
  352. return this.each(function () {
  353. Foundation.init.apply(Foundation, [this].concat(args));
  354. return this;
  355. });
  356. };
  357. }(libFuncName, this, this.document));