Advertisement
Guest User

Untitled

a guest
May 31st, 2016
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.54 KB | None | 0 0
  1. /*!
  2. * fancyBox - jQuery Plugin
  3. * version: 2.1.5 (Fri, 14 Jun 2013)
  4. * @requires jQuery v1.6 or later
  5. *
  6. * Examples at http://fancyapps.com/fancybox/
  7. * License: www.fancyapps.com/fancybox/#license
  8. *
  9. * Copyright 2012 Janis Skarnelis - janis@fancyapps.com
  10. *
  11. */
  12.  
  13. (function (window, document, $, undefined) {
  14. "use strict";
  15.  
  16. var H = $("html"),
  17. W = $(window),
  18. D = $(document),
  19. F = $.fancybox = function () {
  20. F.open.apply( this, arguments );
  21. },
  22. IE = navigator.userAgent.match(/msie/i),
  23. didUpdate = null,
  24. isTouch = document.createTouch !== undefined,
  25.  
  26. isQuery = function(obj) {
  27. return obj && obj.hasOwnProperty && obj instanceof $;
  28. },
  29. isString = function(str) {
  30. return str && $.type(str) === "string";
  31. },
  32. isPercentage = function(str) {
  33. return isString(str) && str.indexOf('%') > 0;
  34. },
  35. isScrollable = function(el) {
  36. return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
  37. },
  38. getScalar = function(orig, dim) {
  39. var value = parseInt(orig, 10) || 0;
  40.  
  41. if (dim && isPercentage(orig)) {
  42. value = F.getViewport()[ dim ] / 100 * value;
  43. }
  44.  
  45. return Math.ceil(value);
  46. },
  47. getValue = function(value, dim) {
  48. return getScalar(value, dim) + 'px';
  49. };
  50.  
  51. $.extend(F, {
  52. // The current version of fancyBox
  53. version: '2.1.5',
  54.  
  55. defaults: {
  56. padding : 15,
  57. margin : 20,
  58.  
  59. width : 800,
  60. height : 600,
  61. minWidth : 100,
  62. minHeight : 100,
  63. maxWidth : 9999,
  64. maxHeight : 9999,
  65. pixelRatio: 1, // Set to 2 for retina display support
  66.  
  67. autoSize : true,
  68. autoHeight : false,
  69. autoWidth : false,
  70.  
  71. autoResize : true,
  72. autoCenter : !isTouch,
  73. fitToView : true,
  74. aspectRatio : false,
  75. topRatio : 0.5,
  76. leftRatio : 0.5,
  77.  
  78. scrolling : 'auto', // 'auto', 'yes' or 'no'
  79. wrapCSS : '',
  80.  
  81. arrows : true,
  82. closeBtn : true,
  83. closeClick : false,
  84. nextClick : false,
  85. mouseWheel : true,
  86. autoPlay : false,
  87. playSpeed : 3000,
  88. preload : 3,
  89. modal : false,
  90. loop : true,
  91.  
  92. ajax : {
  93. dataType : 'html',
  94. headers : { 'X-fancyBox': true }
  95. },
  96. iframe : {
  97. scrolling : 'auto',
  98. preload : true
  99. },
  100. swf : {
  101. wmode: 'transparent',
  102. allowfullscreen : 'true',
  103. allowscriptaccess : 'always'
  104. },
  105.  
  106. keys : {
  107. next : {
  108. 13 : 'left', // enter
  109. 34 : 'up', // page down
  110. 39 : 'left', // right arrow
  111. 40 : 'up' // down arrow
  112. },
  113. prev : {
  114. 8 : 'right', // backspace
  115. 33 : 'down', // page up
  116. 37 : 'right', // left arrow
  117. 38 : 'down' // up arrow
  118. },
  119. close : [27], // escape key
  120. play : [32], // space - start/stop slideshow
  121. toggle : [70] // letter "f" - toggle fullscreen
  122. },
  123.  
  124. direction : {
  125. next : 'left',
  126. prev : 'right'
  127. },
  128.  
  129. scrollOutside : true,
  130.  
  131. // Override some properties
  132. index : 0,
  133. type : null,
  134. href : null,
  135. content : null,
  136. title : null,
  137.  
  138. // HTML templates
  139. tpl: {
  140. wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
  141. image : '<img class="fancybox-image" src="{href}" alt="" />',
  142. iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
  143. error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
  144. closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
  145. next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
  146. prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
  147. },
  148.  
  149. // Properties for each animation type
  150. // Opening fancyBox
  151. openEffect : 'fade', // 'elastic', 'fade' or 'none'
  152. openSpeed : 250,
  153. openEasing : 'swing',
  154. openOpacity : true,
  155. openMethod : 'zoomIn',
  156.  
  157. // Closing fancyBox
  158. closeEffect : 'fade', // 'elastic', 'fade' or 'none'
  159. closeSpeed : 250,
  160. closeEasing : 'swing',
  161. closeOpacity : true,
  162. closeMethod : 'zoomOut',
  163.  
  164. // Changing next gallery item
  165. nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
  166. nextSpeed : 250,
  167. nextEasing : 'swing',
  168. nextMethod : 'changeIn',
  169.  
  170. // Changing previous gallery item
  171. prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
  172. prevSpeed : 250,
  173. prevEasing : 'swing',
  174. prevMethod : 'changeOut',
  175.  
  176. // Enable default helpers
  177. helpers : {
  178. overlay : true,
  179. title : true
  180. },
  181.  
  182. // Callbacks
  183. onCancel : $.noop, // If canceling
  184. beforeLoad : $.noop, // Before loading
  185. afterLoad : $.noop, // After loading
  186. beforeShow : $.noop, // Before changing in current item
  187. afterShow : $.noop, // After opening
  188. beforeChange : $.noop, // Before changing gallery item
  189. beforeClose : $.noop, // Before closing
  190. afterClose : $.noop // After closing
  191. },
  192.  
  193. //Current state
  194. group : {}, // Selected group
  195. opts : {}, // Group options
  196. previous : null, // Previous element
  197. coming : null, // Element being loaded
  198. current : null, // Currently loaded element
  199. isActive : false, // Is activated
  200. isOpen : false, // Is currently open
  201. isOpened : false, // Have been fully opened at least once
  202.  
  203. wrap : null,
  204. skin : null,
  205. outer : null,
  206. inner : null,
  207.  
  208. player : {
  209. timer : null,
  210. isActive : false
  211. },
  212.  
  213. // Loaders
  214. ajaxLoad : null,
  215. imgPreload : null,
  216.  
  217. // Some collections
  218. transitions : {},
  219. helpers : {},
  220.  
  221. /*
  222. * Static methods
  223. */
  224.  
  225. open: function (group, opts) {
  226. if (!group) {
  227. return;
  228. }
  229.  
  230. if (!$.isPlainObject(opts)) {
  231. opts = {};
  232. }
  233.  
  234. // Close if already active
  235. if (false === F.close(true)) {
  236. return;
  237. }
  238.  
  239. // Normalize group
  240. if (!$.isArray(group)) {
  241. group = isQuery(group) ? $(group).get() : [group];
  242. }
  243.  
  244. // Recheck if the type of each element is `object` and set content type (image, ajax, etc)
  245. $.each(group, function(i, element) {
  246. var obj = {},
  247. href,
  248. title,
  249. content,
  250. type,
  251. rez,
  252. hrefParts,
  253. selector;
  254.  
  255. if ($.type(element) === "object") {
  256. // Check if is DOM element
  257. if (element.nodeType) {
  258. element = $(element);
  259. }
  260.  
  261. if (isQuery(element)) {
  262. obj = {
  263. href : element.data('fancybox-href') || element.attr('href'),
  264. title : element.data('fancybox-title') || element.attr('title'),
  265. isDom : true,
  266. element : element
  267. };
  268.  
  269. if ($.metadata) {
  270. $.extend(true, obj, element.metadata());
  271. }
  272.  
  273. } else {
  274. obj = element;
  275. }
  276. }
  277.  
  278. href = opts.href || obj.href || (isString(element) ? element : null);
  279. title = opts.title !== undefined ? opts.title : obj.title || '';
  280.  
  281. content = opts.content || obj.content;
  282. type = content ? 'html' : (opts.type || obj.type);
  283.  
  284. if (!type && obj.isDom) {
  285. type = element.data('fancybox-type');
  286.  
  287. if (!type) {
  288. rez = element.prop('class').match(/fancybox\.(\w+)/);
  289. type = rez ? rez[1] : null;
  290. }
  291. }
  292.  
  293. if (isString(href)) {
  294. // Try to guess the content type
  295. if (!type) {
  296. if (F.isImage(href)) {
  297. type = 'image';
  298.  
  299. } else if (F.isSWF(href)) {
  300. type = 'swf';
  301.  
  302. } else if (href.charAt(0) === '#') {
  303. type = 'inline';
  304.  
  305. } else if (isString(element)) {
  306. type = 'html';
  307. content = element;
  308. }
  309. }
  310.  
  311. // Split url into two pieces with source url and content selector, e.g,
  312. // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
  313. if (type === 'ajax') {
  314. hrefParts = href.split(/\s+/, 2);
  315. href = hrefParts.shift();
  316. selector = hrefParts.shift();
  317. }
  318. }
  319.  
  320. if (!content) {
  321. if (type === 'inline') {
  322. if (href) {
  323. content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
  324.  
  325. } else if (obj.isDom) {
  326. content = element;
  327. }
  328.  
  329. } else if (type === 'html') {
  330. content = href;
  331.  
  332. } else if (!type && !href && obj.isDom) {
  333. type = 'inline';
  334. content = element;
  335. }
  336. }
  337.  
  338. $.extend(obj, {
  339. href : href,
  340. type : type,
  341. content : content,
  342. title : title,
  343. selector : selector
  344. });
  345.  
  346. group[ i ] = obj;
  347. });
  348.  
  349. // Extend the defaults
  350. F.opts = $.extend(true, {}, F.defaults, opts);
  351.  
  352. // All options are merged recursive except keys
  353. if (opts.keys !== undefined) {
  354. F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
  355. }
  356.  
  357. F.group = group;
  358.  
  359. return F._start(F.opts.index);
  360. },
  361.  
  362. // Cancel image loading or abort ajax request
  363. cancel: function () {
  364. var coming = F.coming;
  365.  
  366. if (!coming || false === F.trigger('onCancel')) {
  367. return;
  368. }
  369.  
  370. F.hideLoading();
  371.  
  372. if (F.ajaxLoad) {
  373. F.ajaxLoad.abort();
  374. }
  375.  
  376. F.ajaxLoad = null;
  377.  
  378. if (F.imgPreload) {
  379. F.imgPreload.onload = F.imgPreload.onerror = null;
  380. }
  381.  
  382. if (coming.wrap) {
  383. coming.wrap.stop(true, true).trigger('onReset').remove();
  384. }
  385.  
  386. F.coming = null;
  387.  
  388. // If the first item has been canceled, then clear everything
  389. if (!F.current) {
  390. F._afterZoomOut( coming );
  391. }
  392. },
  393.  
  394. // Start closing animation if is open; remove immediately if opening/closing
  395. close: function (event) {
  396. F.cancel();
  397.  
  398. if (false === F.trigger('beforeClose')) {
  399. return;
  400. }
  401.  
  402. F.unbindEvents();
  403.  
  404. if (!F.isActive) {
  405. return;
  406. }
  407.  
  408. if (!F.isOpen || event === true) {
  409. $('.fancybox-wrap').stop(true).trigger('onReset').remove();
  410.  
  411. F._afterZoomOut();
  412.  
  413. } else {
  414. F.isOpen = F.isOpened = false;
  415. F.isClosing = true;
  416.  
  417. $('.fancybox-item, .fancybox-nav').remove();
  418.  
  419. F.wrap.stop(true, true).removeClass('fancybox-opened');
  420.  
  421. F.transitions[ F.current.closeMethod ]();
  422. }
  423. },
  424.  
  425. // Manage slideshow:
  426. // $.fancybox.play(); - toggle slideshow
  427. // $.fancybox.play( true ); - start
  428. // $.fancybox.play( false ); - stop
  429. play: function ( action ) {
  430. var clear = function () {
  431. clearTimeout(F.player.timer);
  432. },
  433. set = function () {
  434. clear();
  435.  
  436. if (F.current && F.player.isActive) {
  437. F.player.timer = setTimeout(F.next, F.current.playSpeed);
  438. }
  439. },
  440. stop = function () {
  441. clear();
  442.  
  443. D.unbind('.player');
  444.  
  445. F.player.isActive = false;
  446.  
  447. F.trigger('onPlayEnd');
  448. },
  449. start = function () {
  450. if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
  451. F.player.isActive = true;
  452.  
  453. D.bind({
  454. 'onCancel.player beforeClose.player' : stop,
  455. 'onUpdate.player' : set,
  456. 'beforeLoad.player' : clear
  457. });
  458.  
  459. set();
  460.  
  461. F.trigger('onPlayStart');
  462. }
  463. };
  464.  
  465. if (action === true || (!F.player.isActive && action !== false)) {
  466. start();
  467. } else {
  468. stop();
  469. }
  470. },
  471.  
  472. // Navigate to next gallery item
  473. next: function ( direction ) {
  474. var current = F.current;
  475.  
  476. if (current) {
  477. if (!isString(direction)) {
  478. direction = current.direction.next;
  479. }
  480.  
  481. F.jumpto(current.index + 1, direction, 'next');
  482. }
  483. },
  484.  
  485. // Navigate to previous gallery item
  486. prev: function ( direction ) {
  487. var current = F.current;
  488.  
  489. if (current) {
  490. if (!isString(direction)) {
  491. direction = current.direction.prev;
  492. }
  493.  
  494. F.jumpto(current.index - 1, direction, 'prev');
  495. }
  496. },
  497.  
  498. // Navigate to gallery item by index
  499. jumpto: function ( index, direction, router ) {
  500. var current = F.current;
  501.  
  502. if (!current) {
  503. return;
  504. }
  505.  
  506. index = getScalar(index);
  507.  
  508. F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
  509. F.router = router || 'jumpto';
  510.  
  511. if (current.loop) {
  512. if (index < 0) {
  513. index = current.group.length + (index % current.group.length);
  514. }
  515.  
  516. index = index % current.group.length;
  517. }
  518.  
  519. if (current.group[ index ] !== undefined) {
  520. F.cancel();
  521.  
  522. F._start(index);
  523. }
  524. },
  525.  
  526. // Center inside viewport and toggle position type to fixed or absolute if needed
  527. reposition: function (e, onlyAbsolute) {
  528. var current = F.current,
  529. wrap = current ? current.wrap : null,
  530. pos;
  531.  
  532. if (wrap) {
  533. pos = F._getPosition(onlyAbsolute);
  534.  
  535. if (e && e.type === 'scroll') {
  536. delete pos.position;
  537.  
  538. wrap.stop(true, true).animate(pos, 200);
  539.  
  540. } else {
  541. wrap.css(pos);
  542.  
  543. current.pos = $.extend({}, current.dim, pos);
  544. }
  545. }
  546. },
  547.  
  548. update: function (e) {
  549. var type = (e && e.type),
  550. anyway = !type || type === 'orientationchange';
  551.  
  552. if (anyway) {
  553. clearTimeout(didUpdate);
  554.  
  555. didUpdate = null;
  556. }
  557.  
  558. if (!F.isOpen || didUpdate) {
  559. return;
  560. }
  561.  
  562. didUpdate = setTimeout(function() {
  563. var current = F.current;
  564.  
  565. if (!current || F.isClosing) {
  566. return;
  567. }
  568.  
  569. F.wrap.removeClass('fancybox-tmp');
  570.  
  571. if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
  572. F._setDimension();
  573. }
  574.  
  575. if (!(type === 'scroll' && current.canShrink)) {
  576. F.reposition(e);
  577. }
  578.  
  579. F.trigger('onUpdate');
  580.  
  581. didUpdate = null;
  582.  
  583. }, (anyway && !isTouch ? 0 : 300));
  584. },
  585.  
  586. // Shrink content to fit inside viewport or restore if resized
  587. toggle: function ( action ) {
  588. if (F.isOpen) {
  589. F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
  590.  
  591. // Help browser to restore document dimensions
  592. if (isTouch) {
  593. F.wrap.removeAttr('style').addClass('fancybox-tmp');
  594.  
  595. F.trigger('onUpdate');
  596. }
  597.  
  598. F.update();
  599. }
  600. },
  601.  
  602. hideLoading: function () {
  603. D.unbind('.loading');
  604.  
  605. $('#fancybox-loading').remove();
  606. },
  607.  
  608. showLoading: function () {
  609. var el, viewport;
  610.  
  611. F.hideLoading();
  612.  
  613. el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
  614.  
  615. // If user will press the escape-button, the request will be canceled
  616. D.bind('keydown.loading', function(e) {
  617. if ((e.which || e.keyCode) === 27) {
  618. e.preventDefault();
  619.  
  620. F.cancel();
  621. }
  622. });
  623.  
  624. if (!F.defaults.fixed) {
  625. viewport = F.getViewport();
  626.  
  627. el.css({
  628. position : 'absolute',
  629. top : (viewport.h * 0.5) + viewport.y,
  630. left : (viewport.w * 0.5) + viewport.x
  631. });
  632. }
  633. },
  634.  
  635. getViewport: function () {
  636. var locked = (F.current && F.current.locked) || false,
  637. rez = {
  638. x: W.scrollLeft(),
  639. y: W.scrollTop()
  640. };
  641.  
  642. if (locked) {
  643. rez.w = locked[0].clientWidth;
  644. rez.h = locked[0].clientHeight;
  645.  
  646. } else {
  647. // See http://bugs.jquery.com/ticket/6724
  648. rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width();
  649. rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
  650. }
  651.  
  652. return rez;
  653. },
  654.  
  655. // Unbind the keyboard / clicking actions
  656. unbindEvents: function () {
  657. if (F.wrap && isQuery(F.wrap)) {
  658. F.wrap.unbind('.fb');
  659. }
  660.  
  661. D.unbind('.fb');
  662. W.unbind('.fb');
  663. },
  664.  
  665. bindEvents: function () {
  666. var current = F.current,
  667. keys;
  668.  
  669. if (!current) {
  670. return;
  671. }
  672.  
  673. // Changing document height on iOS devices triggers a 'resize' event,
  674. // that can change document height... repeating infinitely
  675. W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
  676.  
  677. keys = current.keys;
  678.  
  679. if (keys) {
  680. D.bind('keydown.fb', function (e) {
  681. var code = e.which || e.keyCode,
  682. target = e.target || e.srcElement;
  683.  
  684. // Skip esc key if loading, because showLoading will cancel preloading
  685. if (code === 27 && F.coming) {
  686. return false;
  687. }
  688.  
  689. // Ignore key combinations and key events within form elements
  690. if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
  691. $.each(keys, function(i, val) {
  692. if (current.group.length > 1 && val[ code ] !== undefined) {
  693. F[ i ]( val[ code ] );
  694.  
  695. e.preventDefault();
  696. return false;
  697. }
  698.  
  699. if ($.inArray(code, val) > -1) {
  700. F[ i ] ();
  701.  
  702. e.preventDefault();
  703. return false;
  704. }
  705. });
  706. }
  707. });
  708. }
  709.  
  710. if ($.fn.mousewheel && current.mouseWheel) {
  711. F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
  712. var target = e.target || null,
  713. parent = $(target),
  714. canScroll = false;
  715.  
  716. while (parent.length) {
  717. if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {
  718. break;
  719. }
  720.  
  721. canScroll = isScrollable( parent[0] );
  722. parent = $(parent).parent();
  723. }
  724.  
  725. if (delta !== 0 && !canScroll) {
  726. if (F.group.length > 1 && !current.canShrink) {
  727. if (deltaY > 0 || deltaX > 0) {
  728. F.prev( deltaY > 0 ? 'down' : 'left' );
  729.  
  730. } else if (deltaY < 0 || deltaX < 0) {
  731. F.next( deltaY < 0 ? 'up' : 'right' );
  732. }
  733.  
  734. e.preventDefault();
  735. }
  736. }
  737. });
  738. }
  739. },
  740.  
  741. trigger: function (event, o) {
  742. var ret, obj = o || F.coming || F.current;
  743.  
  744. if (!obj) {
  745. return;
  746. }
  747.  
  748. if ($.isFunction( obj[event] )) {
  749. ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
  750. }
  751.  
  752. if (ret === false) {
  753. return false;
  754. }
  755.  
  756. if (obj.helpers) {
  757. $.each(obj.helpers, function (helper, opts) {
  758. if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
  759. F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);
  760. }
  761. });
  762. }
  763.  
  764. D.trigger(event);
  765. },
  766.  
  767. isImage: function (str) {
  768. return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
  769. },
  770.  
  771. isSWF: function (str) {
  772. return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
  773. },
  774.  
  775. _start: function (index) {
  776. var coming = {},
  777. obj,
  778. href,
  779. type,
  780. margin,
  781. padding;
  782.  
  783. index = getScalar( index );
  784. obj = F.group[ index ] || null;
  785.  
  786. if (!obj) {
  787. return false;
  788. }
  789.  
  790. coming = $.extend(true, {}, F.opts, obj);
  791.  
  792. // Convert margin and padding properties to array - top, right, bottom, left
  793. margin = coming.margin;
  794. padding = coming.padding;
  795.  
  796. if ($.type(margin) === 'number') {
  797. coming.margin = [margin, margin, margin, margin];
  798. }
  799.  
  800. if ($.type(padding) === 'number') {
  801. coming.padding = [padding, padding, padding, padding];
  802. }
  803.  
  804. // 'modal' propery is just a shortcut
  805. if (coming.modal) {
  806. $.extend(true, coming, {
  807. closeBtn : false,
  808. closeClick : false,
  809. nextClick : false,
  810. arrows : false,
  811. mouseWheel : false,
  812. keys : null,
  813. helpers: {
  814. overlay : {
  815. closeClick : false
  816. }
  817. }
  818. });
  819. }
  820.  
  821. // 'autoSize' property is a shortcut, too
  822. if (coming.autoSize) {
  823. coming.autoWidth = coming.autoHeight = true;
  824. }
  825.  
  826. if (coming.width === 'auto') {
  827. coming.autoWidth = true;
  828. }
  829.  
  830. if (coming.height === 'auto') {
  831. coming.autoHeight = true;
  832. }
  833.  
  834. /*
  835. * Add reference to the group, so it`s possible to access from callbacks, example:
  836. * afterLoad : function() {
  837. * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
  838. * }
  839. */
  840.  
  841. coming.group = F.group;
  842. coming.index = index;
  843.  
  844. // Give a chance for callback or helpers to update coming item (type, title, etc)
  845. F.coming = coming;
  846.  
  847. if (false === F.trigger('beforeLoad')) {
  848. F.coming = null;
  849.  
  850. return;
  851. }
  852.  
  853. type = coming.type;
  854. href = coming.href;
  855.  
  856. if (!type) {
  857. F.coming = null;
  858.  
  859. //If we can not determine content type then drop silently or display next/prev item if looping through gallery
  860. if (F.current && F.router && F.router !== 'jumpto') {
  861. F.current.index = index;
  862.  
  863. return F[ F.router ]( F.direction );
  864. }
  865.  
  866. return false;
  867. }
  868.  
  869. F.isActive = true;
  870.  
  871. if (type === 'image' || type === 'swf') {
  872. coming.autoHeight = coming.autoWidth = false;
  873. coming.scrolling = 'visible';
  874. }
  875.  
  876. if (type === 'image') {
  877. coming.aspectRatio = true;
  878. }
  879.  
  880. if (type === 'iframe' && isTouch) {
  881. coming.scrolling = 'scroll';
  882. }
  883.  
  884. // Build the neccessary markup
  885. coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
  886.  
  887. $.extend(coming, {
  888. skin : $('.fancybox-skin', coming.wrap),
  889. outer : $('.fancybox-outer', coming.wrap),
  890. inner : $('.fancybox-inner', coming.wrap)
  891. });
  892.  
  893. $.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
  894. coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
  895. });
  896.  
  897. F.trigger('onReady');
  898.  
  899. // Check before try to load; 'inline' and 'html' types need content, others - href
  900. if (type === 'inline' || type === 'html') {
  901. if (!coming.content || !coming.content.length) {
  902. return F._error( 'content' );
  903. }
  904.  
  905. } else if (!href) {
  906. return F._error( 'href' );
  907. }
  908.  
  909. if (type === 'image') {
  910. F._loadImage();
  911.  
  912. } else if (type === 'ajax') {
  913. F._loadAjax();
  914.  
  915. } else if (type === 'iframe') {
  916. F._loadIframe();
  917.  
  918. } else {
  919. F._afterLoad();
  920. }
  921. },
  922.  
  923. _error: function ( type ) {
  924. $.extend(F.coming, {
  925. type : 'html',
  926. autoWidth : true,
  927. autoHeight : true,
  928. minWidth : 0,
  929. minHeight : 0,
  930. scrolling : 'no',
  931. hasError : type,
  932. content : F.coming.tpl.error
  933. });
  934.  
  935. F._afterLoad();
  936. },
  937.  
  938. _loadImage: function () {
  939. // Reset preload image so it is later possible to check "complete" property
  940. var img = F.imgPreload = new Image();
  941.  
  942. img.onload = function () {
  943. this.onload = this.onerror = null;
  944.  
  945. F.coming.width = this.width / F.opts.pixelRatio;
  946. F.coming.height = this.height / F.opts.pixelRatio;
  947.  
  948. F._afterLoad();
  949. };
  950.  
  951. img.onerror = function () {
  952. this.onload = this.onerror = null;
  953.  
  954. F._error( 'image' );
  955. };
  956.  
  957. img.src = F.coming.href;
  958.  
  959. if (img.complete !== true) {
  960. F.showLoading();
  961. }
  962. },
  963.  
  964. _loadAjax: function () {
  965. var coming = F.coming;
  966.  
  967. F.showLoading();
  968.  
  969. F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
  970. url: coming.href,
  971. error: function (jqXHR, textStatus) {
  972. if (F.coming && textStatus !== 'abort') {
  973. F._error( 'ajax', jqXHR );
  974.  
  975. } else {
  976. F.hideLoading();
  977. }
  978. },
  979. success: function (data, textStatus) {
  980. if (textStatus === 'success') {
  981. coming.content = data;
  982.  
  983. F._afterLoad();
  984. }
  985. }
  986. }));
  987. },
  988.  
  989. _loadIframe: function() {
  990. var coming = F.coming,
  991. iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
  992. .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
  993. .attr('src', coming.href);
  994.  
  995. // This helps IE
  996. $(coming.wrap).bind('onReset', function () {
  997. try {
  998. $(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
  999. } catch (e) {}
  1000. });
  1001.  
  1002. if (coming.iframe.preload) {
  1003. F.showLoading();
  1004.  
  1005. iframe.one('load', function() {
  1006. $(this).data('ready', 1);
  1007.  
  1008. // iOS will lose scrolling if we resize
  1009. if (!isTouch) {
  1010. $(this).bind('load.fb', F.update);
  1011. }
  1012.  
  1013. // Without this trick:
  1014. // - iframe won't scroll on iOS devices
  1015. // - IE7 sometimes displays empty iframe
  1016. $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();
  1017.  
  1018. F._afterLoad();
  1019. });
  1020. }
  1021.  
  1022. coming.content = iframe.appendTo( coming.inner );
  1023.  
  1024. if (!coming.iframe.preload) {
  1025. F._afterLoad();
  1026. }
  1027. },
  1028.  
  1029. _preloadImages: function() {
  1030. var group = F.group,
  1031. current = F.current,
  1032. len = group.length,
  1033. cnt = current.preload ? Math.min(current.preload, len - 1) : 0,
  1034. item,
  1035. i;
  1036.  
  1037. for (i = 1; i <= cnt; i += 1) {
  1038. item = group[ (current.index + i ) % len ];
  1039.  
  1040. if (item.type === 'image' && item.href) {
  1041. new Image().src = item.href;
  1042. }
  1043. }
  1044. },
  1045.  
  1046. _afterLoad: function () {
  1047. var coming = F.coming,
  1048. previous = F.current,
  1049. placeholder = 'fancybox-placeholder',
  1050. current,
  1051. content,
  1052. type,
  1053. scrolling,
  1054. href,
  1055. embed;
  1056.  
  1057. F.hideLoading();
  1058.  
  1059. if (!coming || F.isActive === false) {
  1060. return;
  1061. }
  1062.  
  1063. if (false === F.trigger('afterLoad', coming, previous)) {
  1064. coming.wrap.stop(true).trigger('onReset').remove();
  1065.  
  1066. F.coming = null;
  1067.  
  1068. return;
  1069. }
  1070.  
  1071. if (previous) {
  1072. F.trigger('beforeChange', previous);
  1073.  
  1074. previous.wrap.stop(true).removeClass('fancybox-opened')
  1075. .find('.fancybox-item, .fancybox-nav')
  1076. .remove();
  1077. }
  1078.  
  1079. F.unbindEvents();
  1080.  
  1081. current = coming;
  1082. content = coming.content;
  1083. type = coming.type;
  1084. scrolling = coming.scrolling;
  1085.  
  1086. $.extend(F, {
  1087. wrap : current.wrap,
  1088. skin : current.skin,
  1089. outer : current.outer,
  1090. inner : current.inner,
  1091. current : current,
  1092. previous : previous
  1093. });
  1094.  
  1095. href = current.href;
  1096.  
  1097. switch (type) {
  1098. case 'inline':
  1099. case 'ajax':
  1100. case 'html':
  1101. if (current.selector) {
  1102. content = $('<div>').html(content).find(current.selector);
  1103.  
  1104. } else if (isQuery(content)) {
  1105. if (!content.data(placeholder)) {
  1106. content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
  1107. }
  1108.  
  1109. content = content.show().detach();
  1110.  
  1111. current.wrap.bind('onReset', function () {
  1112. if ($(this).find(content).length) {
  1113. content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
  1114. }
  1115. });
  1116. }
  1117. break;
  1118.  
  1119. case 'image':
  1120. content = current.tpl.image.replace('{href}', href);
  1121. break;
  1122.  
  1123. case 'swf':
  1124. content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
  1125. embed = '';
  1126.  
  1127. $.each(current.swf, function(name, val) {
  1128. content += '<param name="' + name + '" value="' + val + '"></param>';
  1129. embed += ' ' + name + '="' + val + '"';
  1130. });
  1131.  
  1132. content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
  1133. break;
  1134. }
  1135.  
  1136. if (!(isQuery(content) && content.parent().is(current.inner))) {
  1137. current.inner.append( content );
  1138. }
  1139.  
  1140. // Give a chance for helpers or callbacks to update elements
  1141. F.trigger('beforeShow');
  1142.  
  1143. // Set scrolling before calculating dimensions
  1144. current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
  1145.  
  1146. // Set initial dimensions and start position
  1147. F._setDimension();
  1148.  
  1149. F.reposition();
  1150.  
  1151. F.isOpen = false;
  1152. F.coming = null;
  1153.  
  1154. F.bindEvents();
  1155.  
  1156. if (!F.isOpened) {
  1157. $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
  1158.  
  1159. } else if (previous.prevMethod) {
  1160. F.transitions[ previous.prevMethod ]();
  1161. }
  1162.  
  1163. F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
  1164.  
  1165. F._preloadImages();
  1166. },
  1167.  
  1168. _setDimension: function () {
  1169. var viewport = F.getViewport(),
  1170. steps = 0,
  1171. canShrink = false,
  1172. canExpand = false,
  1173. wrap = F.wrap,
  1174. skin = F.skin,
  1175. inner = F.inner,
  1176. current = F.current,
  1177. width = current.width,
  1178. height = current.height,
  1179. minWidth = current.minWidth,
  1180. minHeight = current.minHeight,
  1181. maxWidth = current.maxWidth,
  1182. maxHeight = current.maxHeight,
  1183. scrolling = current.scrolling,
  1184. scrollOut = current.scrollOutside ? current.scrollbarWidth : 0,
  1185. margin = current.margin,
  1186. wMargin = getScalar(margin[1] + margin[3]),
  1187. hMargin = getScalar(margin[0] + margin[2]),
  1188. wPadding,
  1189. hPadding,
  1190. wSpace,
  1191. hSpace,
  1192. origWidth,
  1193. origHeight,
  1194. origMaxWidth,
  1195. origMaxHeight,
  1196. ratio,
  1197. width_,
  1198. height_,
  1199. maxWidth_,
  1200. maxHeight_,
  1201. iframe,
  1202. body;
  1203.  
  1204. // Reset dimensions so we could re-check actual size
  1205. wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
  1206.  
  1207. wPadding = getScalar(skin.outerWidth(true) - skin.width());
  1208. hPadding = getScalar(skin.outerHeight(true) - skin.height());
  1209.  
  1210. // Any space between content and viewport (margin, padding, border, title)
  1211. wSpace = wMargin + wPadding;
  1212. hSpace = hMargin + hPadding;
  1213.  
  1214. origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width;
  1215. origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
  1216.  
  1217. if (current.type === 'iframe') {
  1218. iframe = current.content;
  1219.  
  1220. if (current.autoHeight && iframe.data('ready') === 1) {
  1221. try {
  1222. if (iframe[0].contentWindow.document.location) {
  1223. inner.width( origWidth ).height(9999);
  1224.  
  1225. body = iframe.contents().find('body');
  1226.  
  1227. if (scrollOut) {
  1228. body.css('overflow-x', 'hidden');
  1229. }
  1230.  
  1231. origHeight = body.outerHeight(true);
  1232. }
  1233.  
  1234. } catch (e) {}
  1235. }
  1236.  
  1237. } else if (current.autoWidth || current.autoHeight) {
  1238. inner.addClass( 'fancybox-tmp' );
  1239.  
  1240. // Set width or height in case we need to calculate only one dimension
  1241. if (!current.autoWidth) {
  1242. inner.width( origWidth );
  1243. }
  1244.  
  1245. if (!current.autoHeight) {
  1246. inner.height( origHeight );
  1247. }
  1248.  
  1249. if (current.autoWidth) {
  1250. origWidth = inner.width();
  1251. }
  1252.  
  1253. if (current.autoHeight) {
  1254. origHeight = inner.height();
  1255. }
  1256.  
  1257. inner.removeClass( 'fancybox-tmp' );
  1258. }
  1259.  
  1260. width = getScalar( origWidth );
  1261. height = getScalar( origHeight );
  1262.  
  1263. ratio = origWidth / origHeight;
  1264.  
  1265. // Calculations for the content
  1266. minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
  1267. maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
  1268.  
  1269. minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
  1270. maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
  1271.  
  1272. // These will be used to determine if wrap can fit in the viewport
  1273. origMaxWidth = maxWidth;
  1274. origMaxHeight = maxHeight;
  1275.  
  1276. if (current.fitToView) {
  1277. maxWidth = Math.min(viewport.w - wSpace, maxWidth);
  1278. maxHeight = Math.min(viewport.h - hSpace, maxHeight);
  1279. }
  1280.  
  1281. maxWidth_ = viewport.w - wMargin;
  1282. maxHeight_ = viewport.h - hMargin;
  1283.  
  1284. if (current.aspectRatio) {
  1285. if (width > maxWidth) {
  1286. width = maxWidth;
  1287. height = getScalar(width / ratio);
  1288. }
  1289.  
  1290. if (height > maxHeight) {
  1291. height = maxHeight;
  1292. width = getScalar(height * ratio);
  1293. }
  1294.  
  1295. if (width < minWidth) {
  1296. width = minWidth;
  1297. height = getScalar(width / ratio);
  1298. }
  1299.  
  1300. if (height < minHeight) {
  1301. height = minHeight;
  1302. width = getScalar(height * ratio);
  1303. }
  1304.  
  1305. } else {
  1306. width = Math.max(minWidth, Math.min(width, maxWidth));
  1307.  
  1308. if (current.autoHeight && current.type !== 'iframe') {
  1309. inner.width( width );
  1310.  
  1311. height = inner.height();
  1312. }
  1313.  
  1314. height = Math.max(minHeight, Math.min(height, maxHeight));
  1315. }
  1316.  
  1317. // Try to fit inside viewport (including the title)
  1318. if (current.fitToView) {
  1319. inner.width( width ).height( height );
  1320.  
  1321. wrap.width( width + wPadding );
  1322.  
  1323. // Real wrap dimensions
  1324. width_ = wrap.width();
  1325. height_ = wrap.height();
  1326.  
  1327. if (current.aspectRatio) {
  1328. while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
  1329. if (steps++ > 19) {
  1330. break;
  1331. }
  1332.  
  1333. height = Math.max(minHeight, Math.min(maxHeight, height - 10));
  1334. width = getScalar(height * ratio);
  1335.  
  1336. if (width < minWidth) {
  1337. width = minWidth;
  1338. height = getScalar(width / ratio);
  1339. }
  1340.  
  1341. if (width > maxWidth) {
  1342. width = maxWidth;
  1343. height = getScalar(width / ratio);
  1344. }
  1345.  
  1346. inner.width( width ).height( height );
  1347.  
  1348. wrap.width( width + wPadding );
  1349.  
  1350. width_ = wrap.width();
  1351. height_ = wrap.height();
  1352. }
  1353.  
  1354. } else {
  1355. width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_)));
  1356. height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
  1357. }
  1358. }
  1359.  
  1360. if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
  1361. width += scrollOut;
  1362. }
  1363.  
  1364. inner.width( width ).height( height );
  1365.  
  1366. wrap.width( width + wPadding );
  1367.  
  1368. width_ = wrap.width();
  1369. height_ = wrap.height();
  1370.  
  1371. canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
  1372. canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
  1373.  
  1374. $.extend(current, {
  1375. dim : {
  1376. width : getValue( width_ ),
  1377. height : getValue( height_ )
  1378. },
  1379. origWidth : origWidth,
  1380. origHeight : origHeight,
  1381. canShrink : canShrink,
  1382. canExpand : canExpand,
  1383. wPadding : wPadding,
  1384. hPadding : hPadding,
  1385. wrapSpace : height_ - skin.outerHeight(true),
  1386. skinSpace : skin.height() - height
  1387. });
  1388.  
  1389. if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
  1390. inner.height('auto');
  1391. }
  1392. },
  1393.  
  1394. _getPosition: function (onlyAbsolute) {
  1395. var current = F.current,
  1396. viewport = F.getViewport(),
  1397. margin = current.margin,
  1398. width = F.wrap.width() + margin[1] + margin[3],
  1399. height = F.wrap.height() + margin[0] + margin[2],
  1400. rez = {
  1401. position: 'absolute',
  1402. top : margin[0],
  1403. left : margin[3]
  1404. };
  1405.  
  1406. if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
  1407. rez.position = 'fixed';
  1408.  
  1409. } else if (!current.locked) {
  1410. rez.top += viewport.y;
  1411. rez.left += viewport.x;
  1412. }
  1413.  
  1414. rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio)));
  1415. rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio)));
  1416.  
  1417. return rez;
  1418. },
  1419.  
  1420. _afterZoomIn: function () {
  1421. var current = F.current;
  1422.  
  1423. if (!current) {
  1424. return;
  1425. }
  1426.  
  1427. F.isOpen = F.isOpened = true;
  1428.  
  1429. F.wrap.css('overflow', 'visible').addClass('fancybox-opened');
  1430.  
  1431. F.update();
  1432.  
  1433. // Assign a click event
  1434. if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
  1435. F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
  1436. if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
  1437. e.preventDefault();
  1438.  
  1439. F[ current.closeClick ? 'close' : 'next' ]();
  1440. }
  1441. });
  1442. }
  1443.  
  1444. // Create a close button
  1445. if (current.closeBtn) {
  1446. $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
  1447. e.preventDefault();
  1448.  
  1449. F.close();
  1450. });
  1451. }
  1452.  
  1453. // Create navigation arrows
  1454. if (current.arrows && F.group.length > 1) {
  1455. if (current.loop || current.index > 0) {
  1456. $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
  1457. }
  1458.  
  1459. if (current.loop || current.index < F.group.length - 1) {
  1460. $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
  1461. }
  1462. }
  1463.  
  1464. F.trigger('afterShow');
  1465.  
  1466. // Stop the slideshow if this is the last item
  1467. if (!current.loop && current.index === current.group.length - 1) {
  1468. F.play( false );
  1469.  
  1470. } else if (F.opts.autoPlay && !F.player.isActive) {
  1471. F.opts.autoPlay = false;
  1472.  
  1473. F.play();
  1474. }
  1475. },
  1476.  
  1477. _afterZoomOut: function ( obj ) {
  1478. obj = obj || F.current;
  1479.  
  1480. $('.fancybox-wrap').trigger('onReset').remove();
  1481.  
  1482. $.extend(F, {
  1483. group : {},
  1484. opts : {},
  1485. router : false,
  1486. current : null,
  1487. isActive : false,
  1488. isOpened : false,
  1489. isOpen : false,
  1490. isClosing : false,
  1491. wrap : null,
  1492. skin : null,
  1493. outer : null,
  1494. inner : null
  1495. });
  1496.  
  1497. F.trigger('afterClose', obj);
  1498. }
  1499. });
  1500.  
  1501. /*
  1502. * Default transitions
  1503. */
  1504.  
  1505. F.transitions = {
  1506. getOrigPosition: function () {
  1507. var current = F.current,
  1508. element = current.element,
  1509. orig = current.orig,
  1510. pos = {},
  1511. width = 50,
  1512. height = 50,
  1513. hPadding = current.hPadding,
  1514. wPadding = current.wPadding,
  1515. viewport = F.getViewport();
  1516.  
  1517. if (!orig && current.isDom && element.is(':visible')) {
  1518. orig = element.find('img:first');
  1519.  
  1520. if (!orig.length) {
  1521. orig = element;
  1522. }
  1523. }
  1524.  
  1525. if (isQuery(orig)) {
  1526. pos = orig.offset();
  1527.  
  1528. if (orig.is('img')) {
  1529. width = orig.outerWidth();
  1530. height = orig.outerHeight();
  1531. }
  1532.  
  1533. } else {
  1534. pos.top = viewport.y + (viewport.h - height) * current.topRatio;
  1535. pos.left = viewport.x + (viewport.w - width) * current.leftRatio;
  1536. }
  1537.  
  1538. if (F.wrap.css('position') === 'fixed' || current.locked) {
  1539. pos.top -= viewport.y;
  1540. pos.left -= viewport.x;
  1541. }
  1542.  
  1543. pos = {
  1544. top : getValue(pos.top - hPadding * current.topRatio),
  1545. left : getValue(pos.left - wPadding * current.leftRatio),
  1546. width : getValue(width + wPadding),
  1547. height : getValue(height + hPadding)
  1548. };
  1549.  
  1550. return pos;
  1551. },
  1552.  
  1553. step: function (now, fx) {
  1554. var ratio,
  1555. padding,
  1556. value,
  1557. prop = fx.prop,
  1558. current = F.current,
  1559. wrapSpace = current.wrapSpace,
  1560. skinSpace = current.skinSpace;
  1561.  
  1562. if (prop === 'width' || prop === 'height') {
  1563. ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
  1564.  
  1565. if (F.isClosing) {
  1566. ratio = 1 - ratio;
  1567. }
  1568.  
  1569. padding = prop === 'width' ? current.wPadding : current.hPadding;
  1570. value = now - padding;
  1571.  
  1572. F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) );
  1573. F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
  1574. }
  1575. },
  1576.  
  1577. zoomIn: function () {
  1578. var current = F.current,
  1579. startPos = current.pos,
  1580. effect = current.openEffect,
  1581. elastic = effect === 'elastic',
  1582. endPos = $.extend({opacity : 1}, startPos);
  1583.  
  1584. // Remove "position" property that breaks older IE
  1585. delete endPos.position;
  1586.  
  1587. if (elastic) {
  1588. startPos = this.getOrigPosition();
  1589.  
  1590. if (current.openOpacity) {
  1591. startPos.opacity = 0.1;
  1592. }
  1593.  
  1594. } else if (effect === 'fade') {
  1595. startPos.opacity = 0.1;
  1596. }
  1597.  
  1598. F.wrap.css(startPos).animate(endPos, {
  1599. duration : effect === 'none' ? 0 : current.openSpeed,
  1600. easing : current.openEasing,
  1601. step : elastic ? this.step : null,
  1602. complete : F._afterZoomIn
  1603. });
  1604. },
  1605.  
  1606. zoomOut: function () {
  1607. var current = F.current,
  1608. effect = current.closeEffect,
  1609. elastic = effect === 'elastic',
  1610. endPos = {opacity : 0.1};
  1611.  
  1612. if (elastic) {
  1613. endPos = this.getOrigPosition();
  1614.  
  1615. if (current.closeOpacity) {
  1616. endPos.opacity = 0.1;
  1617. }
  1618. }
  1619.  
  1620. F.wrap.animate(endPos, {
  1621. duration : effect === 'none' ? 0 : current.closeSpeed,
  1622. easing : current.closeEasing,
  1623. step : elastic ? this.step : null,
  1624. complete : F._afterZoomOut
  1625. });
  1626. },
  1627.  
  1628. changeIn: function () {
  1629. var current = F.current,
  1630. effect = current.nextEffect,
  1631. startPos = current.pos,
  1632. endPos = { opacity : 1 },
  1633. direction = F.direction,
  1634. distance = 200,
  1635. field;
  1636.  
  1637. startPos.opacity = 0.1;
  1638.  
  1639. if (effect === 'elastic') {
  1640. field = direction === 'down' || direction === 'up' ? 'top' : 'left';
  1641.  
  1642. if (direction === 'down' || direction === 'right') {
  1643. startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
  1644. endPos[ field ] = '+=' + distance + 'px';
  1645.  
  1646. } else {
  1647. startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
  1648. endPos[ field ] = '-=' + distance + 'px';
  1649. }
  1650. }
  1651.  
  1652. // Workaround for http://bugs.jquery.com/ticket/12273
  1653. if (effect === 'none') {
  1654. F._afterZoomIn();
  1655.  
  1656. } else {
  1657. F.wrap.css(startPos).animate(endPos, {
  1658. duration : current.nextSpeed,
  1659. easing : current.nextEasing,
  1660. complete : F._afterZoomIn
  1661. });
  1662. }
  1663. },
  1664.  
  1665. changeOut: function () {
  1666. var previous = F.previous,
  1667. effect = previous.prevEffect,
  1668. endPos = { opacity : 0.1 },
  1669. direction = F.direction,
  1670. distance = 200;
  1671.  
  1672. if (effect === 'elastic') {
  1673. endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
  1674. }
  1675.  
  1676. previous.wrap.animate(endPos, {
  1677. duration : effect === 'none' ? 0 : previous.prevSpeed,
  1678. easing : previous.prevEasing,
  1679. complete : function () {
  1680. $(this).trigger('onReset').remove();
  1681. }
  1682. });
  1683. }
  1684. };
  1685.  
  1686. /*
  1687. * Overlay helper
  1688. */
  1689.  
  1690. F.helpers.overlay = {
  1691. defaults : {
  1692. closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay
  1693. speedOut : 200, // duration of fadeOut animation
  1694. showEarly : true, // indicates if should be opened immediately or wait until the content is ready
  1695. css : {}, // custom CSS properties
  1696. locked : !isTouch, // if true, the content will be locked into overlay
  1697. fixed : true // if false, the overlay CSS position property will not be set to "fixed"
  1698. },
  1699.  
  1700. overlay : null, // current handle
  1701. fixed : false, // indicates if the overlay has position "fixed"
  1702. el : $('html'), // element that contains "the lock"
  1703.  
  1704. // Public methods
  1705. create : function(opts) {
  1706. opts = $.extend({}, this.defaults, opts);
  1707.  
  1708. if (this.overlay) {
  1709. this.close();
  1710. }
  1711.  
  1712. this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent );
  1713. this.fixed = false;
  1714.  
  1715. if (opts.fixed && F.defaults.fixed) {
  1716. this.overlay.addClass('fancybox-overlay-fixed');
  1717.  
  1718. this.fixed = true;
  1719. }
  1720. },
  1721.  
  1722. open : function(opts) {
  1723. var that = this;
  1724.  
  1725. opts = $.extend({}, this.defaults, opts);
  1726.  
  1727. if (this.overlay) {
  1728. this.overlay.unbind('.overlay').width('auto').height('auto');
  1729.  
  1730. } else {
  1731. this.create(opts);
  1732. }
  1733.  
  1734. if (!this.fixed) {
  1735. W.bind('resize.overlay', $.proxy( this.update, this) );
  1736.  
  1737. this.update();
  1738. }
  1739.  
  1740. if (opts.closeClick) {
  1741. this.overlay.bind('click.overlay', function(e) {
  1742. if ($(e.target).hasClass('fancybox-overlay')) {
  1743. if (F.isActive) {
  1744. F.close();
  1745. } else {
  1746. that.close();
  1747. }
  1748.  
  1749. return false;
  1750. }
  1751. });
  1752. }
  1753.  
  1754. this.overlay.css( opts.css ).show();
  1755. },
  1756.  
  1757. close : function() {
  1758. var scrollV, scrollH;
  1759.  
  1760. W.unbind('resize.overlay');
  1761.  
  1762. if (this.el.hasClass('fancybox-lock')) {
  1763. $('.fancybox-margin').removeClass('fancybox-margin');
  1764.  
  1765. scrollV = W.scrollTop();
  1766. scrollH = W.scrollLeft();
  1767.  
  1768. this.el.removeClass('fancybox-lock');
  1769.  
  1770. W.scrollTop( scrollV ).scrollLeft( scrollH );
  1771. }
  1772.  
  1773. $('.fancybox-overlay').remove().hide();
  1774.  
  1775. $.extend(this, {
  1776. overlay : null,
  1777. fixed : false
  1778. });
  1779. },
  1780.  
  1781. // Private, callbacks
  1782.  
  1783. update : function () {
  1784. var width = '100%', offsetWidth;
  1785.  
  1786. // Reset width/height so it will not mess
  1787. this.overlay.width(width).height('100%');
  1788.  
  1789. // jQuery does not return reliable result for IE
  1790. if (IE) {
  1791. offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
  1792.  
  1793. if (D.width() > offsetWidth) {
  1794. width = D.width();
  1795. }
  1796.  
  1797. } else if (D.width() > W.width()) {
  1798. width = D.width();
  1799. }
  1800.  
  1801. this.overlay.width(width).height(D.height());
  1802. },
  1803.  
  1804. // This is where we can manipulate DOM, because later it would cause iframes to reload
  1805. onReady : function (opts, obj) {
  1806. var overlay = this.overlay;
  1807.  
  1808. $('.fancybox-overlay').stop(true, true);
  1809.  
  1810. if (!overlay) {
  1811. this.create(opts);
  1812. }
  1813.  
  1814. if (opts.locked && this.fixed && obj.fixed) {
  1815. if (!overlay) {
  1816. this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false;
  1817. }
  1818.  
  1819. obj.locked = this.overlay.append( obj.wrap );
  1820. obj.fixed = false;
  1821. }
  1822.  
  1823. if (opts.showEarly === true) {
  1824. this.beforeShow.apply(this, arguments);
  1825. }
  1826. },
  1827.  
  1828. beforeShow : function(opts, obj) {
  1829. var scrollV, scrollH;
  1830.  
  1831. if (obj.locked) {
  1832. if (this.margin !== false) {
  1833. $('*').filter(function(){
  1834. return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );
  1835. }).addClass('fancybox-margin');
  1836.  
  1837. this.el.addClass('fancybox-margin');
  1838. }
  1839.  
  1840. scrollV = W.scrollTop();
  1841. scrollH = W.scrollLeft();
  1842.  
  1843. this.el.addClass('fancybox-lock');
  1844.  
  1845. W.scrollTop( scrollV ).scrollLeft( scrollH );
  1846. }
  1847.  
  1848. this.open(opts);
  1849. },
  1850.  
  1851. onUpdate : function() {
  1852. if (!this.fixed) {
  1853. this.update();
  1854. }
  1855. },
  1856.  
  1857. afterClose: function (opts) {
  1858. // Remove overlay if exists and fancyBox is not opening
  1859. // (e.g., it is not being open using afterClose callback)
  1860. //if (this.overlay && !F.isActive) {
  1861. if (this.overlay && !F.coming) {
  1862. this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
  1863. }
  1864. }
  1865. };
  1866.  
  1867. /*
  1868. * Title helper
  1869. */
  1870.  
  1871. F.helpers.title = {
  1872. defaults : {
  1873. type : 'float', // 'float', 'inside', 'outside' or 'over',
  1874. position : 'bottom' // 'top' or 'bottom'
  1875. },
  1876.  
  1877. beforeShow: function (opts) {
  1878. var current = F.current,
  1879. text = current.title,
  1880. type = opts.type,
  1881. title,
  1882. target;
  1883.  
  1884. if ($.isFunction(text)) {
  1885. text = text.call(current.element, current);
  1886. }
  1887.  
  1888. if (!isString(text) || $.trim(text) === '') {
  1889. return;
  1890. }
  1891.  
  1892. title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + '</div>');
  1893.  
  1894. switch (type) {
  1895. case 'inside':
  1896. target = F.skin;
  1897. break;
  1898.  
  1899. case 'outside':
  1900. target = F.wrap;
  1901. break;
  1902.  
  1903. case 'over':
  1904. target = F.inner;
  1905. break;
  1906.  
  1907. default: // 'float'
  1908. target = F.skin;
  1909.  
  1910. title.appendTo('body');
  1911.  
  1912. if (IE) {
  1913. title.width( title.width() );
  1914. }
  1915.  
  1916. title.wrapInner('<span class="child"></span>');
  1917.  
  1918. //Increase bottom margin so this title will also fit into viewport
  1919. F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
  1920. break;
  1921. }
  1922.  
  1923. title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target);
  1924. }
  1925. };
  1926.  
  1927. // jQuery plugin initialization
  1928. $.fn.fancybox = function (options) {
  1929. var index,
  1930. that = $(this),
  1931. selector = this.selector || '',
  1932. run = function(e) {
  1933. var what = $(this).blur(), idx = index, relType, relVal;
  1934.  
  1935. if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
  1936. relType = options.groupAttr || 'data-fancybox-group';
  1937. relVal = what.attr(relType);
  1938.  
  1939. if (!relVal) {
  1940. relType = 'rel';
  1941. relVal = what.get(0)[ relType ];
  1942. }
  1943.  
  1944. if (relVal && relVal !== '' && relVal !== 'nofollow') {
  1945. what = selector.length ? $(selector) : that;
  1946. what = what.filter('[' + relType + '="' + relVal + '"]');
  1947. idx = what.index(this);
  1948. }
  1949.  
  1950. options.index = idx;
  1951.  
  1952. // Stop an event from bubbling if everything is fine
  1953. if (F.open(what, options) !== false) {
  1954. e.preventDefault();
  1955. }
  1956. }
  1957. };
  1958.  
  1959. options = options || {};
  1960. index = options.index || 0;
  1961.  
  1962. if (!selector || options.live === false) {
  1963. that.unbind('click.fb-start').bind('click.fb-start', run);
  1964.  
  1965. } else {
  1966. D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
  1967. }
  1968.  
  1969. this.filter('[data-fancybox-start=1]').trigger('click');
  1970.  
  1971. return this;
  1972. };
  1973.  
  1974. // Tests that need a body at doc ready
  1975. D.ready(function() {
  1976. var w1, w2;
  1977.  
  1978. if ( $.scrollbarWidth === undefined ) {
  1979. // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
  1980. $.scrollbarWidth = function() {
  1981. var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
  1982. child = parent.children(),
  1983. width = child.innerWidth() - child.height( 99 ).innerWidth();
  1984.  
  1985. parent.remove();
  1986.  
  1987. return width;
  1988. };
  1989. }
  1990.  
  1991. if ( $.support.fixedPosition === undefined ) {
  1992. $.support.fixedPosition = (function() {
  1993. var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
  1994. fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
  1995.  
  1996. elem.remove();
  1997.  
  1998. return fixed;
  1999. }());
  2000. }
  2001.  
  2002. $.extend(F.defaults, {
  2003. scrollbarWidth : $.scrollbarWidth(),
  2004. fixed : $.support.fixedPosition,
  2005. parent : $('body')
  2006. });
  2007.  
  2008. //Get real width of page scroll-bar
  2009. w1 = $(window).width();
  2010.  
  2011. H.addClass('fancybox-lock-test');
  2012.  
  2013. w2 = $(window).width();
  2014.  
  2015. H.removeClass('fancybox-lock-test');
  2016.  
  2017. $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
  2018. });
  2019.  
  2020. }(window, document, jQuery));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement