diff --git a/.gitignore b/.gitignore
index 5e52405..56635bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,6 @@ bower.json
# Ignore node_modules
node_modules/
+
+# Ignore master key for decrypting credentials and more.
+/config/master.key
diff --git a/Gemfile b/Gemfile
index ad42699..4f71e55 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,6 +12,8 @@ gem 'coffee-rails', '~> 4.2.1'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
+gem 'sprockets-rails'
+
# Use jquery as the JavaScript library
gem 'jquery-rails'
gem 'jquery-ui-rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index 09ba6b0..48fb39e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -353,6 +353,7 @@ DEPENDENCIES
simplecov
slack-notifier
spring
+ sprockets-rails
sqlite3
timecop
toastr-rails
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index ba8b915..abd12bf 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -13,7 +13,10 @@
//= require jquery
//= require rails-ujs
//= require turbolinks
+//= require popper
//= require bootstrap
-//= require_tree .
+//= require scrollreveal.min.js
//= require toastr
-//= require popper
+//= require jquery.magnific-popup.min.js
+
+//= require_tree .
diff --git a/app/assets/javascripts/creative.coffee b/app/assets/javascripts/creative.coffee
new file mode 100644
index 0000000..af089cc
--- /dev/null
+++ b/app/assets/javascripts/creative.coffee
@@ -0,0 +1,65 @@
+(($) ->
+ 'use strict'
+ # Start of use strict
+ # Smooth scrolling using jQuery easing
+ $('a.js-scroll-trigger[href*="#"]:not([href="#"])').click ->
+ if location.pathname.replace(/^\//, '') == @pathname.replace(/^\//, '') and location.hostname == @hostname
+ target = $(@hash)
+ target = if target.length then target else $('[name=' + @hash.slice(1) + ']')
+ if target.length
+ $('html, body').animate { scrollTop: target.offset().top - 57 }, 1000, 'easeInOutExpo'
+ return false
+ return
+ # Closes responsive menu when a scroll trigger link is clicked
+ $('.js-scroll-trigger').click ->
+ $('.navbar-collapse').collapse 'hide'
+ return
+ # Activate scrollspy to add active class to navbar items on scroll
+ $('body').scrollspy
+ target: '#mainNav'
+ offset: 57
+ # Collapse Navbar
+
+ navbarCollapse = ->
+ if $('#mainNav').offset().top > 100
+ $('#mainNav').addClass 'navbar-shrink'
+ else
+ $('#mainNav').removeClass 'navbar-shrink'
+ return
+
+ # Collapse now if page is not at top
+ $(document).on 'turbolinks:load', navbarCollapse
+ # Collapse the navbar when page is scrolled
+ $(window).scroll navbarCollapse
+ # Scroll reveal calls
+ window.sr = ScrollReveal()
+ sr.reveal '.sr-icons', {
+ duration: 600
+ scale: 0.3
+ distance: '0px'
+ }, 200
+ sr.reveal '.sr-button',
+ duration: 1000
+ delay: 200
+ sr.reveal '.sr-contact', {
+ duration: 600
+ scale: 0.3
+ distance: '0px'
+ }, 300
+ # Magnific popup calls
+ $('.popup-gallery').magnificPopup
+ delegate: 'a'
+ type: 'image'
+ tLoading: 'Loading image #%curr%...'
+ mainClass: 'mfp-img-mobile'
+ gallery:
+ enabled: true
+ navigateByImgClick: true
+ preload: [
+ 0
+ 1
+ ]
+ image: tError: 'The image #%curr% could not be loaded.'
+ return
+) jQuery
+# End of use strict
diff --git a/app/assets/javascripts/creative.js b/app/assets/javascripts/creative.js
deleted file mode 100644
index 7a65340..0000000
--- a/app/assets/javascripts/creative.js
+++ /dev/null
@@ -1,75 +0,0 @@
-(function($) {
- "use strict"; // Start of use strict
-
- // Smooth scrolling using jQuery easing
- $('a.js-scroll-trigger[href*="#"]:not([href="#"])').click(function() {
- if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
- var target = $(this.hash);
- target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
- if (target.length) {
- $('html, body').animate({
- scrollTop: (target.offset().top - 57)
- }, 1000, "easeInOutExpo");
- return false;
- }
- }
- });
-
- // Closes responsive menu when a scroll trigger link is clicked
- $('.js-scroll-trigger').click(function() {
- $('.navbar-collapse').collapse('hide');
- });
-
- // Activate scrollspy to add active class to navbar items on scroll
- $('body').scrollspy({
- target: '#mainNav',
- offset: 57
- });
-
- // Collapse Navbar
- var navbarCollapse = function() {
- if ($("#mainNav").offset().top > 100) {
- $("#mainNav").addClass("navbar-shrink");
- } else {
- $("#mainNav").removeClass("navbar-shrink");
- }
- };
- // Collapse now if page is not at top
- navbarCollapse();
- // Collapse the navbar when page is scrolled
- $(window).scroll(navbarCollapse);
-
- // Scroll reveal calls
- window.sr = ScrollReveal();
- sr.reveal('.sr-icons', {
- duration: 600,
- scale: 0.3,
- distance: '0px'
- }, 200);
- sr.reveal('.sr-button', {
- duration: 1000,
- delay: 200
- });
- sr.reveal('.sr-contact', {
- duration: 600,
- scale: 0.3,
- distance: '0px'
- }, 300);
-
- // Magnific popup calls
- $('.popup-gallery').magnificPopup({
- delegate: 'a',
- type: 'image',
- tLoading: 'Loading image #%curr%...',
- mainClass: 'mfp-img-mobile',
- gallery: {
- enabled: true,
- navigateByImgClick: true,
- preload: [0, 1]
- },
- image: {
- tError: 'The image #%curr% could not be loaded.'
- }
- });
-
-})(jQuery); // End of use strict
diff --git a/app/assets/javascripts/js-check.coffee b/app/assets/javascripts/js-check.coffee
new file mode 100644
index 0000000..6b0646f
--- /dev/null
+++ b/app/assets/javascripts/js-check.coffee
@@ -0,0 +1,7 @@
+$ ->
+ console.log('No Events')
+ $(document).on 'turbolinks:load', callTurbolinks_load_event
+
+callTurbolinks_load_event = ->
+ console.log('turbolinks:load called!')
+ return
diff --git a/app/assets/javascripts/staticpages.coffee b/app/assets/javascripts/staticpages.coffee
index bafcddb..461bd75 100644
--- a/app/assets/javascripts/staticpages.coffee
+++ b/app/assets/javascripts/staticpages.coffee
@@ -2,9 +2,6 @@
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
-document.addEventListener 'turbolinks:load', ->
- componentHandler.upgradeDom()
-
# ((d, s, id) ->
# js = undefined
# fjs = d.getElementsByTagName(s)[0]
@@ -30,4 +27,4 @@ document.addEventListener 'turbolinks:load', ->
# fjs.parentNode.insertBefore js, fjs
# return
# )(document, 'script', 'twitter-wjs')
-# return
\ No newline at end of file
+# return
diff --git a/app/assets/javascripts/twitter.coffee b/app/assets/javascripts/twitter.coffee
index fb760e8..712a809 100644
--- a/app/assets/javascripts/twitter.coffee
+++ b/app/assets/javascripts/twitter.coffee
@@ -1,3 +1,4 @@
+
twttr_events_bound = false
$ ->
@@ -9,7 +10,7 @@ bindTwitterEventHandlers = ->
twttr_events_bound = true
renderTweetButtons = ->
- $('.twitter-follow-button').each ->
+ $('.twitter-share-button').each ->
button = $(this)
button.attr('data-url', document.location.href) unless button.data('url')?
button.attr('data-text', document.title) unless button.data('text')?
@@ -17,3 +18,18 @@ renderTweetButtons = ->
loadTwitterSDK = (callback) ->
$.getScript('//platform.twitter.com/widgets.js', callback)
+
+
+document.addEventListener 'turbolinks:load', ->
+ !((d, s, id) ->
+ js = undefined
+ fjs = d.getElementsByTagName(s)[0]
+ p = if /^http:/.test(d.location) then 'http' else 'https'
+ if !d.getElementById(id)
+ js = d.createElement(s)
+ js.id = id
+ js.src = p + '://platform.twitter.com/widgets.js'
+ fjs.parentNode.insertBefore js, fjs
+ return
+ )(document, 'script', 'twitter-wjs')
+ return
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 5107641..ec6d0e8 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -17,6 +17,8 @@
@import "toastr";
+@import "magnific-popup.css";
+
@import "bootstrap-creative/creative";
@import "pages";
@import "posts";
diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc
new file mode 100644
index 0000000..2d705d0
--- /dev/null
+++ b/config/credentials.yml.enc
@@ -0,0 +1 @@
+93UJISKB7KDNP4+U59DLd7AtYZM2XBaJ73Z2KymZ6uWVm8rT2gd3vN8HkMy4A4ZmOUq8Q7y9Y4iPBhgQoBT990vG4Uvjjntcy5svtdFaGqwb+rp/Vge69FIzloXBYK46Xjgm2hD/gkZKfjru/j5eKmBJeRPbKgezsmFdfFwZVo+wTLoevaLf+X0cezrKzNX3nBB15ZHqe+A2//Sj7cxxO8flgOaeCm3Ukvathdrzv3OI9TfSepdA8CqXPunX55FW+qShgl41R5qZrZ01umwIJW+uCSItG3/bmQ2BKHAK9/TrRiSDUmSit5IxSP3B0ktwJH5Rdt0jSoWLWxr54Aj3K6cyiTbO1cM2BhbYugBTxsHl6Mbx5aXtyOY2wuROvK7TzXnO3w/b00s21fEJLd6/8uZ/fzXd0IPE5YEk--+6JTITAbwvy6yF68--e8oPyx0l4g2Sm+EWUuWwsg==
\ No newline at end of file
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 70f3bfc..a7d7f5d 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -14,7 +14,7 @@
config.eager_load = true
# Full error reports are disabled and caching is turned on.
- config.consider_all_requests_local = false
+ config.consider_all_requests_local = true
config.action_controller.perform_caching = true
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
@@ -23,14 +23,14 @@
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
- config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+ config.public_file_server.enabled = true
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
- config.assets.compile = false
+ config.assets.compile = true
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
diff --git a/vendor/assets/magnific-popup/jquery.magnific-popup.js b/vendor/assets/magnific-popup/jquery.magnific-popup.js
new file mode 100755
index 0000000..927b3c1
--- /dev/null
+++ b/vendor/assets/magnific-popup/jquery.magnific-popup.js
@@ -0,0 +1,1860 @@
+/*! Magnific Popup - v1.1.0 - 2016-02-20
+* http://dimsemenov.com/plugins/magnific-popup/
+* Copyright (c) 2016 Dmitry Semenov; */
+;(function (factory) {
+if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery'], factory);
+ } else if (typeof exports === 'object') {
+ // Node/CommonJS
+ factory(require('jquery'));
+ } else {
+ // Browser globals
+ factory(window.jQuery || window.Zepto);
+ }
+ }(function($) {
+
+/*>>core*/
+/**
+ *
+ * Magnific Popup Core JS file
+ *
+ */
+
+
+/**
+ * Private static constants
+ */
+var CLOSE_EVENT = 'Close',
+ BEFORE_CLOSE_EVENT = 'BeforeClose',
+ AFTER_CLOSE_EVENT = 'AfterClose',
+ BEFORE_APPEND_EVENT = 'BeforeAppend',
+ MARKUP_PARSE_EVENT = 'MarkupParse',
+ OPEN_EVENT = 'Open',
+ CHANGE_EVENT = 'Change',
+ NS = 'mfp',
+ EVENT_NS = '.' + NS,
+ READY_CLASS = 'mfp-ready',
+ REMOVING_CLASS = 'mfp-removing',
+ PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
+
+
+/**
+ * Private vars
+ */
+/*jshint -W079 */
+var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
+ MagnificPopup = function(){},
+ _isJQ = !!(window.jQuery),
+ _prevStatus,
+ _window = $(window),
+ _document,
+ _prevContentType,
+ _wrapClasses,
+ _currPopupType;
+
+
+/**
+ * Private functions
+ */
+var _mfpOn = function(name, f) {
+ mfp.ev.on(NS + name + EVENT_NS, f);
+ },
+ _getEl = function(className, appendTo, html, raw) {
+ var el = document.createElement('div');
+ el.className = 'mfp-'+className;
+ if(html) {
+ el.innerHTML = html;
+ }
+ if(!raw) {
+ el = $(el);
+ if(appendTo) {
+ el.appendTo(appendTo);
+ }
+ } else if(appendTo) {
+ appendTo.appendChild(el);
+ }
+ return el;
+ },
+ _mfpTrigger = function(e, data) {
+ mfp.ev.triggerHandler(NS + e, data);
+
+ if(mfp.st.callbacks) {
+ // converts "mfpEventName" to "eventName" callback and triggers it if it's present
+ e = e.charAt(0).toLowerCase() + e.slice(1);
+ if(mfp.st.callbacks[e]) {
+ mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);
+ }
+ }
+ },
+ _getCloseBtn = function(type) {
+ if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
+ mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
+ _currPopupType = type;
+ }
+ return mfp.currTemplate.closeBtn;
+ },
+ // Initialize Magnific Popup only when called at least once
+ _checkInstance = function() {
+ if(!$.magnificPopup.instance) {
+ /*jshint -W020 */
+ mfp = new MagnificPopup();
+ mfp.init();
+ $.magnificPopup.instance = mfp;
+ }
+ },
+ // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
+ supportsTransitions = function() {
+ var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
+ v = ['ms','O','Moz','Webkit']; // 'v' for vendor
+
+ if( s['transition'] !== undefined ) {
+ return true;
+ }
+
+ while( v.length ) {
+ if( v.pop() + 'Transition' in s ) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+
+
+/**
+ * Public functions
+ */
+MagnificPopup.prototype = {
+
+ constructor: MagnificPopup,
+
+ /**
+ * Initializes Magnific Popup plugin.
+ * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
+ */
+ init: function() {
+ var appVersion = navigator.appVersion;
+ mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
+ mfp.isAndroid = (/android/gi).test(appVersion);
+ mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
+ mfp.supportsTransition = supportsTransitions();
+
+ // We disable fixed positioned lightbox on devices that don't handle it nicely.
+ // If you know a better way of detecting this - let me know.
+ mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
+ _document = $(document);
+
+ mfp.popupsCache = {};
+ },
+
+ /**
+ * Opens popup
+ * @param data [description]
+ */
+ open: function(data) {
+
+ var i;
+
+ if(data.isObj === false) {
+ // convert jQuery collection to array to avoid conflicts later
+ mfp.items = data.items.toArray();
+
+ mfp.index = 0;
+ var items = data.items,
+ item;
+ for(i = 0; i < items.length; i++) {
+ item = items[i];
+ if(item.parsed) {
+ item = item.el[0];
+ }
+ if(item === data.el[0]) {
+ mfp.index = i;
+ break;
+ }
+ }
+ } else {
+ mfp.items = $.isArray(data.items) ? data.items : [data.items];
+ mfp.index = data.index || 0;
+ }
+
+ // if popup is already opened - we just update the content
+ if(mfp.isOpen) {
+ mfp.updateItemHTML();
+ return;
+ }
+
+ mfp.types = [];
+ _wrapClasses = '';
+ if(data.mainEl && data.mainEl.length) {
+ mfp.ev = data.mainEl.eq(0);
+ } else {
+ mfp.ev = _document;
+ }
+
+ if(data.key) {
+ if(!mfp.popupsCache[data.key]) {
+ mfp.popupsCache[data.key] = {};
+ }
+ mfp.currTemplate = mfp.popupsCache[data.key];
+ } else {
+ mfp.currTemplate = {};
+ }
+
+
+
+ mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
+ mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
+
+ if(mfp.st.modal) {
+ mfp.st.closeOnContentClick = false;
+ mfp.st.closeOnBgClick = false;
+ mfp.st.showCloseBtn = false;
+ mfp.st.enableEscapeKey = false;
+ }
+
+
+ // Building markup
+ // main containers are created only once
+ if(!mfp.bgOverlay) {
+
+ // Dark overlay
+ mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
+ mfp.close();
+ });
+
+ mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
+ if(mfp._checkIfClose(e.target)) {
+ mfp.close();
+ }
+ });
+
+ mfp.container = _getEl('container', mfp.wrap);
+ }
+
+ mfp.contentContainer = _getEl('content');
+ if(mfp.st.preloader) {
+ mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
+ }
+
+
+ // Initializing modules
+ var modules = $.magnificPopup.modules;
+ for(i = 0; i < modules.length; i++) {
+ var n = modules[i];
+ n = n.charAt(0).toUpperCase() + n.slice(1);
+ mfp['init'+n].call(mfp);
+ }
+ _mfpTrigger('BeforeOpen');
+
+
+ if(mfp.st.showCloseBtn) {
+ // Close button
+ if(!mfp.st.closeBtnInside) {
+ mfp.wrap.append( _getCloseBtn() );
+ } else {
+ _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
+ values.close_replaceWith = _getCloseBtn(item.type);
+ });
+ _wrapClasses += ' mfp-close-btn-in';
+ }
+ }
+
+ if(mfp.st.alignTop) {
+ _wrapClasses += ' mfp-align-top';
+ }
+
+
+
+ if(mfp.fixedContentPos) {
+ mfp.wrap.css({
+ overflow: mfp.st.overflowY,
+ overflowX: 'hidden',
+ overflowY: mfp.st.overflowY
+ });
+ } else {
+ mfp.wrap.css({
+ top: _window.scrollTop(),
+ position: 'absolute'
+ });
+ }
+ if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
+ mfp.bgOverlay.css({
+ height: _document.height(),
+ position: 'absolute'
+ });
+ }
+
+
+
+ if(mfp.st.enableEscapeKey) {
+ // Close on ESC key
+ _document.on('keyup' + EVENT_NS, function(e) {
+ if(e.keyCode === 27) {
+ mfp.close();
+ }
+ });
+ }
+
+ _window.on('resize' + EVENT_NS, function() {
+ mfp.updateSize();
+ });
+
+
+ if(!mfp.st.closeOnContentClick) {
+ _wrapClasses += ' mfp-auto-cursor';
+ }
+
+ if(_wrapClasses)
+ mfp.wrap.addClass(_wrapClasses);
+
+
+ // this triggers recalculation of layout, so we get it once to not to trigger twice
+ var windowHeight = mfp.wH = _window.height();
+
+
+ var windowStyles = {};
+
+ if( mfp.fixedContentPos ) {
+ if(mfp._hasScrollBar(windowHeight)){
+ var s = mfp._getScrollbarSize();
+ if(s) {
+ windowStyles.marginRight = s;
+ }
+ }
+ }
+
+ if(mfp.fixedContentPos) {
+ if(!mfp.isIE7) {
+ windowStyles.overflow = 'hidden';
+ } else {
+ // ie7 double-scroll bug
+ $('body, html').css('overflow', 'hidden');
+ }
+ }
+
+
+
+ var classesToadd = mfp.st.mainClass;
+ if(mfp.isIE7) {
+ classesToadd += ' mfp-ie7';
+ }
+ if(classesToadd) {
+ mfp._addClassToMFP( classesToadd );
+ }
+
+ // add content
+ mfp.updateItemHTML();
+
+ _mfpTrigger('BuildControls');
+
+ // remove scrollbar, add margin e.t.c
+ $('html').css(windowStyles);
+
+ // add everything to DOM
+ mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
+
+ // Save last focused element
+ mfp._lastFocusedEl = document.activeElement;
+
+ // Wait for next cycle to allow CSS transition
+ setTimeout(function() {
+
+ if(mfp.content) {
+ mfp._addClassToMFP(READY_CLASS);
+ mfp._setFocus();
+ } else {
+ // if content is not defined (not loaded e.t.c) we add class only for BG
+ mfp.bgOverlay.addClass(READY_CLASS);
+ }
+
+ // Trap the focus in popup
+ _document.on('focusin' + EVENT_NS, mfp._onFocusIn);
+
+ }, 16);
+
+ mfp.isOpen = true;
+ mfp.updateSize(windowHeight);
+ _mfpTrigger(OPEN_EVENT);
+
+ return data;
+ },
+
+ /**
+ * Closes the popup
+ */
+ close: function() {
+ if(!mfp.isOpen) return;
+ _mfpTrigger(BEFORE_CLOSE_EVENT);
+
+ mfp.isOpen = false;
+ // for CSS3 animation
+ if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) {
+ mfp._addClassToMFP(REMOVING_CLASS);
+ setTimeout(function() {
+ mfp._close();
+ }, mfp.st.removalDelay);
+ } else {
+ mfp._close();
+ }
+ },
+
+ /**
+ * Helper for close() function
+ */
+ _close: function() {
+ _mfpTrigger(CLOSE_EVENT);
+
+ var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
+
+ mfp.bgOverlay.detach();
+ mfp.wrap.detach();
+ mfp.container.empty();
+
+ if(mfp.st.mainClass) {
+ classesToRemove += mfp.st.mainClass + ' ';
+ }
+
+ mfp._removeClassFromMFP(classesToRemove);
+
+ if(mfp.fixedContentPos) {
+ var windowStyles = {marginRight: ''};
+ if(mfp.isIE7) {
+ $('body, html').css('overflow', '');
+ } else {
+ windowStyles.overflow = '';
+ }
+ $('html').css(windowStyles);
+ }
+
+ _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
+ mfp.ev.off(EVENT_NS);
+
+ // clean up DOM elements that aren't removed
+ mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
+ mfp.bgOverlay.attr('class', 'mfp-bg');
+ mfp.container.attr('class', 'mfp-container');
+
+ // remove close button from target element
+ if(mfp.st.showCloseBtn &&
+ (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
+ if(mfp.currTemplate.closeBtn)
+ mfp.currTemplate.closeBtn.detach();
+ }
+
+
+ if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
+ $(mfp._lastFocusedEl).focus(); // put tab focus back
+ }
+ mfp.currItem = null;
+ mfp.content = null;
+ mfp.currTemplate = null;
+ mfp.prevHeight = 0;
+
+ _mfpTrigger(AFTER_CLOSE_EVENT);
+ },
+
+ updateSize: function(winHeight) {
+
+ if(mfp.isIOS) {
+ // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
+ var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
+ var height = window.innerHeight * zoomLevel;
+ mfp.wrap.css('height', height);
+ mfp.wH = height;
+ } else {
+ mfp.wH = winHeight || _window.height();
+ }
+ // Fixes #84: popup incorrectly positioned with position:relative on body
+ if(!mfp.fixedContentPos) {
+ mfp.wrap.css('height', mfp.wH);
+ }
+
+ _mfpTrigger('Resize');
+
+ },
+
+ /**
+ * Set content of popup based on current index
+ */
+ updateItemHTML: function() {
+ var item = mfp.items[mfp.index];
+
+ // Detach and perform modifications
+ mfp.contentContainer.detach();
+
+ if(mfp.content)
+ mfp.content.detach();
+
+ if(!item.parsed) {
+ item = mfp.parseEl( mfp.index );
+ }
+
+ var type = item.type;
+
+ _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
+ // BeforeChange event works like so:
+ // _mfpOn('BeforeChange', function(e, prevType, newType) { });
+
+ mfp.currItem = item;
+
+ if(!mfp.currTemplate[type]) {
+ var markup = mfp.st[type] ? mfp.st[type].markup : false;
+
+ // allows to modify markup
+ _mfpTrigger('FirstMarkupParse', markup);
+
+ if(markup) {
+ mfp.currTemplate[type] = $(markup);
+ } else {
+ // if there is no markup found we just define that template is parsed
+ mfp.currTemplate[type] = true;
+ }
+ }
+
+ if(_prevContentType && _prevContentType !== item.type) {
+ mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
+ }
+
+ var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
+ mfp.appendContent(newContent, type);
+
+ item.preloaded = true;
+
+ _mfpTrigger(CHANGE_EVENT, item);
+ _prevContentType = item.type;
+
+ // Append container back after its content changed
+ mfp.container.prepend(mfp.contentContainer);
+
+ _mfpTrigger('AfterChange');
+ },
+
+
+ /**
+ * Set HTML content of popup
+ */
+ appendContent: function(newContent, type) {
+ mfp.content = newContent;
+
+ if(newContent) {
+ if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
+ mfp.currTemplate[type] === true) {
+ // if there is no markup, we just append close button element inside
+ if(!mfp.content.find('.mfp-close').length) {
+ mfp.content.append(_getCloseBtn());
+ }
+ } else {
+ mfp.content = newContent;
+ }
+ } else {
+ mfp.content = '';
+ }
+
+ _mfpTrigger(BEFORE_APPEND_EVENT);
+ mfp.container.addClass('mfp-'+type+'-holder');
+
+ mfp.contentContainer.append(mfp.content);
+ },
+
+
+ /**
+ * Creates Magnific Popup data object based on given data
+ * @param {int} index Index of item to parse
+ */
+ parseEl: function(index) {
+ var item = mfp.items[index],
+ type;
+
+ if(item.tagName) {
+ item = { el: $(item) };
+ } else {
+ type = item.type;
+ item = { data: item, src: item.src };
+ }
+
+ if(item.el) {
+ var types = mfp.types;
+
+ // check for 'mfp-TYPE' class
+ for(var i = 0; i < types.length; i++) {
+ if( item.el.hasClass('mfp-'+types[i]) ) {
+ type = types[i];
+ break;
+ }
+ }
+
+ item.src = item.el.attr('data-mfp-src');
+ if(!item.src) {
+ item.src = item.el.attr('href');
+ }
+ }
+
+ item.type = type || mfp.st.type || 'inline';
+ item.index = index;
+ item.parsed = true;
+ mfp.items[index] = item;
+ _mfpTrigger('ElementParse', item);
+
+ return mfp.items[index];
+ },
+
+
+ /**
+ * Initializes single popup or a group of popups
+ */
+ addGroup: function(el, options) {
+ var eHandler = function(e) {
+ e.mfpEl = this;
+ mfp._openClick(e, el, options);
+ };
+
+ if(!options) {
+ options = {};
+ }
+
+ var eName = 'click.magnificPopup';
+ options.mainEl = el;
+
+ if(options.items) {
+ options.isObj = true;
+ el.off(eName).on(eName, eHandler);
+ } else {
+ options.isObj = false;
+ if(options.delegate) {
+ el.off(eName).on(eName, options.delegate , eHandler);
+ } else {
+ options.items = el;
+ el.off(eName).on(eName, eHandler);
+ }
+ }
+ },
+ _openClick: function(e, el, options) {
+ var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
+
+
+ if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
+ return;
+ }
+
+ var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
+
+ if(disableOn) {
+ if($.isFunction(disableOn)) {
+ if( !disableOn.call(mfp) ) {
+ return true;
+ }
+ } else { // else it's number
+ if( _window.width() < disableOn ) {
+ return true;
+ }
+ }
+ }
+
+ if(e.type) {
+ e.preventDefault();
+
+ // This will prevent popup from closing if element is inside and popup is already opened
+ if(mfp.isOpen) {
+ e.stopPropagation();
+ }
+ }
+
+ options.el = $(e.mfpEl);
+ if(options.delegate) {
+ options.items = el.find(options.delegate);
+ }
+ mfp.open(options);
+ },
+
+
+ /**
+ * Updates text on preloader
+ */
+ updateStatus: function(status, text) {
+
+ if(mfp.preloader) {
+ if(_prevStatus !== status) {
+ mfp.container.removeClass('mfp-s-'+_prevStatus);
+ }
+
+ if(!text && status === 'loading') {
+ text = mfp.st.tLoading;
+ }
+
+ var data = {
+ status: status,
+ text: text
+ };
+ // allows to modify status
+ _mfpTrigger('UpdateStatus', data);
+
+ status = data.status;
+ text = data.text;
+
+ mfp.preloader.html(text);
+
+ mfp.preloader.find('a').on('click', function(e) {
+ e.stopImmediatePropagation();
+ });
+
+ mfp.container.addClass('mfp-s-'+status);
+ _prevStatus = status;
+ }
+ },
+
+
+ /*
+ "Private" helpers that aren't private at all
+ */
+ // Check to close popup or not
+ // "target" is an element that was clicked
+ _checkIfClose: function(target) {
+
+ if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
+ return;
+ }
+
+ var closeOnContent = mfp.st.closeOnContentClick;
+ var closeOnBg = mfp.st.closeOnBgClick;
+
+ if(closeOnContent && closeOnBg) {
+ return true;
+ } else {
+
+ // We close the popup if click is on close button or on preloader. Or if there is no content.
+ if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
+ return true;
+ }
+
+ // if click is outside the content
+ if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) {
+ if(closeOnBg) {
+ // last check, if the clicked element is in DOM, (in case it's removed onclick)
+ if( $.contains(document, target) ) {
+ return true;
+ }
+ }
+ } else if(closeOnContent) {
+ return true;
+ }
+
+ }
+ return false;
+ },
+ _addClassToMFP: function(cName) {
+ mfp.bgOverlay.addClass(cName);
+ mfp.wrap.addClass(cName);
+ },
+ _removeClassFromMFP: function(cName) {
+ this.bgOverlay.removeClass(cName);
+ mfp.wrap.removeClass(cName);
+ },
+ _hasScrollBar: function(winHeight) {
+ return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
+ },
+ _setFocus: function() {
+ (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
+ },
+ _onFocusIn: function(e) {
+ if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
+ mfp._setFocus();
+ return false;
+ }
+ },
+ _parseMarkup: function(template, values, item) {
+ var arr;
+ if(item.data) {
+ values = $.extend(item.data, values);
+ }
+ _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
+
+ $.each(values, function(key, value) {
+ if(value === undefined || value === false) {
+ return true;
+ }
+ arr = key.split('_');
+ if(arr.length > 1) {
+ var el = template.find(EVENT_NS + '-'+arr[0]);
+
+ if(el.length > 0) {
+ var attr = arr[1];
+ if(attr === 'replaceWith') {
+ if(el[0] !== value[0]) {
+ el.replaceWith(value);
+ }
+ } else if(attr === 'img') {
+ if(el.is('img')) {
+ el.attr('src', value);
+ } else {
+ el.replaceWith( $('').attr('src', value).attr('class', el.attr('class')) );
+ }
+ } else {
+ el.attr(arr[1], value);
+ }
+ }
+
+ } else {
+ template.find(EVENT_NS + '-'+key).html(value);
+ }
+ });
+ },
+
+ _getScrollbarSize: function() {
+ // thx David
+ if(mfp.scrollbarSize === undefined) {
+ var scrollDiv = document.createElement("div");
+ scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
+ document.body.appendChild(scrollDiv);
+ mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
+ document.body.removeChild(scrollDiv);
+ }
+ return mfp.scrollbarSize;
+ }
+
+}; /* MagnificPopup core prototype end */
+
+
+
+
+/**
+ * Public static functions
+ */
+$.magnificPopup = {
+ instance: null,
+ proto: MagnificPopup.prototype,
+ modules: [],
+
+ open: function(options, index) {
+ _checkInstance();
+
+ if(!options) {
+ options = {};
+ } else {
+ options = $.extend(true, {}, options);
+ }
+
+ options.isObj = true;
+ options.index = index || 0;
+ return this.instance.open(options);
+ },
+
+ close: function() {
+ return $.magnificPopup.instance && $.magnificPopup.instance.close();
+ },
+
+ registerModule: function(name, module) {
+ if(module.options) {
+ $.magnificPopup.defaults[name] = module.options;
+ }
+ $.extend(this.proto, module.proto);
+ this.modules.push(name);
+ },
+
+ defaults: {
+
+ // Info about options is in docs:
+ // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
+
+ disableOn: 0,
+
+ key: null,
+
+ midClick: false,
+
+ mainClass: '',
+
+ preloader: true,
+
+ focus: '', // CSS selector of input to focus after popup is opened
+
+ closeOnContentClick: false,
+
+ closeOnBgClick: true,
+
+ closeBtnInside: true,
+
+ showCloseBtn: true,
+
+ enableEscapeKey: true,
+
+ modal: false,
+
+ alignTop: false,
+
+ removalDelay: 0,
+
+ prependTo: null,
+
+ fixedContentPos: 'auto',
+
+ fixedBgPos: 'auto',
+
+ overflowY: 'auto',
+
+ closeMarkup: '',
+
+ tClose: 'Close (Esc)',
+
+ tLoading: 'Loading...',
+
+ autoFocusLast: true
+
+ }
+};
+
+
+
+$.fn.magnificPopup = function(options) {
+ _checkInstance();
+
+ var jqEl = $(this);
+
+ // We call some API method of first param is a string
+ if (typeof options === "string" ) {
+
+ if(options === 'open') {
+ var items,
+ itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
+ index = parseInt(arguments[1], 10) || 0;
+
+ if(itemOpts.items) {
+ items = itemOpts.items[index];
+ } else {
+ items = jqEl;
+ if(itemOpts.delegate) {
+ items = items.find(itemOpts.delegate);
+ }
+ items = items.eq( index );
+ }
+ mfp._openClick({mfpEl:items}, jqEl, itemOpts);
+ } else {
+ if(mfp.isOpen)
+ mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
+ }
+
+ } else {
+ // clone options obj
+ options = $.extend(true, {}, options);
+
+ /*
+ * As Zepto doesn't support .data() method for objects
+ * and it works only in normal browsers
+ * we assign "options" object directly to the DOM element. FTW!
+ */
+ if(_isJQ) {
+ jqEl.data('magnificPopup', options);
+ } else {
+ jqEl[0].magnificPopup = options;
+ }
+
+ mfp.addGroup(jqEl, options);
+
+ }
+ return jqEl;
+};
+
+/*>>core*/
+
+/*>>inline*/
+
+var INLINE_NS = 'inline',
+ _hiddenClass,
+ _inlinePlaceholder,
+ _lastInlineElement,
+ _putInlineElementsBack = function() {
+ if(_lastInlineElement) {
+ _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
+ _lastInlineElement = null;
+ }
+ };
+
+$.magnificPopup.registerModule(INLINE_NS, {
+ options: {
+ hiddenClass: 'hide', // will be appended with `mfp-` prefix
+ markup: '',
+ tNotFound: 'Content not found'
+ },
+ proto: {
+
+ initInline: function() {
+ mfp.types.push(INLINE_NS);
+
+ _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
+ _putInlineElementsBack();
+ });
+ },
+
+ getInline: function(item, template) {
+
+ _putInlineElementsBack();
+
+ if(item.src) {
+ var inlineSt = mfp.st.inline,
+ el = $(item.src);
+
+ if(el.length) {
+
+ // If target element has parent - we replace it with placeholder and put it back after popup is closed
+ var parent = el[0].parentNode;
+ if(parent && parent.tagName) {
+ if(!_inlinePlaceholder) {
+ _hiddenClass = inlineSt.hiddenClass;
+ _inlinePlaceholder = _getEl(_hiddenClass);
+ _hiddenClass = 'mfp-'+_hiddenClass;
+ }
+ // replace target inline element with placeholder
+ _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
+ }
+
+ mfp.updateStatus('ready');
+ } else {
+ mfp.updateStatus('error', inlineSt.tNotFound);
+ el = $('