diff --git a/assets/built/casper.js b/assets/built/casper.js new file mode 100644 index 0000000..27f8bed --- /dev/null +++ b/assets/built/casper.js @@ -0,0 +1,2 @@ +!function(n){"use strict";n.fn.fitVids=function(e){var i={customSelector:null,ignore:null};if(!document.getElementById("fit-vids-style")){var t=document.head||document.getElementsByTagName("head")[0],r=document.createElement("div");r.innerHTML='

x

',t.appendChild(r.childNodes[1])}return e&&n.extend(i,e),this.each(function(){var e=['iframe[src*="player.vimeo.com"]','iframe[src*="youtube.com"]','iframe[src*="youtube-nocookie.com"]','iframe[src*="kickstarter.com"][src*="video.html"]',"object","embed"];i.customSelector&&e.push(i.customSelector);var r=".fitvidsignore";i.ignore&&(r=r+", "+i.ignore);var t=n(this).find(e.join(","));(t=(t=t.not("object object")).not(r)).each(function(){var e=n(this);if(!(0
').parent(".fluid-width-video-wrapper").css("padding-top",100*t+"%"),e.removeAttr("height").removeAttr("width")}})})},n.fn.fitVids._count=0}(window.jQuery||window.Zepto),function(c,i){c.Casper||(c.Casper={}),c.Casper.floatingHeader=function(){var r=i.querySelector("#reading-progress"),n=i.querySelector(".floating-header"),o=i.querySelector(".post-full-title"),a=c.scrollY,s=c.innerHeight,d=i.body.clientHeight,l=!1;function e(){l||requestAnimationFrame(t),l=!0}function t(){var e=o.getBoundingClientRect().top+c.scrollY,t=o.offsetHeight+35,i=d-s;e+t<=a?n.classList.add("floating-active"):n.classList.remove("floating-active"),r.setAttribute("max",i),r.setAttribute("value",a),l=!1}c.addEventListener("scroll",function(){a=c.scrollY,e()},{passive:!0}),c.addEventListener("resize",function(){s=c.innerHeight,d=i.body.clientHeight,e()},!1),t()}}(window,document),function(e,t){t.addEventListener("DOMContentLoaded",function(){t.querySelectorAll(".kg-gallery-image img").forEach(function(e){var t=e.closest(".kg-gallery-image"),i=e.attributes.width.value/e.attributes.height.value;t.style.flex=i+" 1 0%"})})}(window,document),function(t,i){var r=i.querySelector("link[rel=next]");if(r){var n=i.querySelector(".post-feed");if(n){var o=300,a=!1,s=!1,d=t.scrollY,l=t.innerHeight,c=i.documentElement.scrollHeight;t.addEventListener("scroll",f,{passive:!0}),t.addEventListener("resize",v),h()}}function u(){if(404===this.status)return t.removeEventListener("scroll",f),void t.removeEventListener("resize",v);this.response.querySelectorAll(".post-card").forEach(function(e){n.appendChild(e)});var e=this.response.querySelector("link[rel=next]");e?r.href=e.href:(t.removeEventListener("scroll",f),t.removeEventListener("resize",v)),c=i.documentElement.scrollHeight,s=a=!1}function e(){if(!s)if(d+l<=c-o)a=!1;else{s=!0;var e=new t.XMLHttpRequest;e.responseType="document",e.addEventListener("load",u),e.open("GET",r.href),e.send(null)}}function h(){a||t.requestAnimationFrame(e),a=!0}function f(){d=t.scrollY,h()}function v(){l=t.innerHeight,c=i.documentElement.scrollHeight,h()}}(window,document); +//# sourceMappingURL=casper.js.map \ No newline at end of file diff --git a/assets/built/casper.js.map b/assets/built/casper.js.map new file mode 100644 index 0000000..132b13d --- /dev/null +++ b/assets/built/casper.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["jquery.fitvids.js","floating-header.js","gallery-card.js","infinitescroll.js"],"names":["$","fn","fitVids","options","settings","customSelector","ignore","document","getElementById","head","getElementsByTagName","div","createElement","innerHTML","appendChild","childNodes","extend","this","each","selectors","push","ignoreList","$allVideos","find","join","not","$this","parents","length","tagName","toLowerCase","parent","css","isNaN","attr","aspectRatio","parseInt","height","width","videoName","_count","wrap","removeAttr","window","jQuery","Zepto","Casper","floatingHeader","progressBar","querySelector","header","title","lastScrollY","scrollY","lastWindowHeight","innerHeight","lastDocumentHeight","body","clientHeight","ticking","requestTick","requestAnimationFrame","update","trigger","getBoundingClientRect","top","triggerOffset","offsetHeight","progressMax","classList","add","remove","setAttribute","addEventListener","passive","querySelectorAll","forEach","image","container","closest","ratio","attributes","value","style","flex","nextElement","feedElement","buffer","loading","documentElement","scrollHeight","onScroll","onResize","onPageLoad","status","removeEventListener","response","item","resNextElement","href","onUpdate","xhr","XMLHttpRequest","responseType","open","send"],"mappings":"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","file":"casper.js","sourcesContent":["/*jshint browser:true */\n/*!\n* FitVids 1.3\n*\n*\n* Copyright 2017, Chris Coyier + Dave Rupert + Ghost Foundation\n* This is an unofficial release, ported by John O'Nolan\n* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/\n* Released under the MIT license\n*\n*/\n\n;(function( $ ){\n\n 'use strict';\n\n $.fn.fitVids = function( options ) {\n var settings = {\n customSelector: null,\n ignore: null\n };\n\n if(!document.getElementById('fit-vids-style')) {\n // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js\n var head = document.head || document.getElementsByTagName('head')[0];\n var css = '.fluid-width-video-container{flex-grow: 1;width:100%;}.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';\n var div = document.createElement(\"div\");\n div.innerHTML = '

x

';\n head.appendChild(div.childNodes[1]);\n }\n\n if ( options ) {\n $.extend( settings, options );\n }\n\n return this.each(function(){\n var selectors = [\n 'iframe[src*=\"player.vimeo.com\"]',\n 'iframe[src*=\"youtube.com\"]',\n 'iframe[src*=\"youtube-nocookie.com\"]',\n 'iframe[src*=\"kickstarter.com\"][src*=\"video.html\"]',\n 'object',\n 'embed'\n ];\n\n if (settings.customSelector) {\n selectors.push(settings.customSelector);\n }\n\n var ignoreList = '.fitvidsignore';\n\n if(settings.ignore) {\n ignoreList = ignoreList + ', ' + settings.ignore;\n }\n\n var $allVideos = $(this).find(selectors.join(','));\n $allVideos = $allVideos.not('object object'); // SwfObj conflict patch\n $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.\n\n $allVideos.each(function(){\n var $this = $(this);\n if($this.parents(ignoreList).length > 0) {\n return; // Disable FitVids on this video.\n }\n if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }\n if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))\n {\n $this.attr('height', 9);\n $this.attr('width', 16);\n }\n var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),\n width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),\n aspectRatio = height / width;\n if(!$this.attr('name')){\n var videoName = 'fitvid' + $.fn.fitVids._count;\n $this.attr('name', videoName);\n $.fn.fitVids._count++;\n }\n $this.wrap('
').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');\n $this.removeAttr('height').removeAttr('width');\n });\n });\n };\n\n // Internal counter for unique video names.\n $.fn.fitVids._count = 0;\n\n// Works with either jQuery or Zepto\n})( window.jQuery || window.Zepto );\n","/* eslint-env browser */\n\n/**\n * Floating header\n * Used on invividual post pages, displays a sticky header with progress indicator\n *\n * Must be triggered manually on relevant pages by calling `Casper.floatingHeader()`\n */\n\n(function (window, document) {\n // set up Casper as a global object\n if (!window.Casper) {\n window.Casper = {};\n }\n\n window.Casper.floatingHeader = function floatingHeader() {\n // NOTE: Scroll performance is poor in Safari\n // - this appears to be due to the events firing much more slowly in Safari.\n // Dropping the scroll event and using only a raf loop results in smoother\n // scrolling but continuous processing even when not scrolling\n\n var progressBar = document.querySelector('#reading-progress');\n var header = document.querySelector('.floating-header');\n var title = document.querySelector('.post-full-title');\n\n var lastScrollY = window.scrollY;\n var lastWindowHeight = window.innerHeight;\n var lastDocumentHeight = document.body.clientHeight;\n var ticking = false;\n\n function onScroll() {\n lastScrollY = window.scrollY;\n requestTick();\n }\n\n function onResize() {\n lastWindowHeight = window.innerHeight;\n lastDocumentHeight = document.body.clientHeight;\n requestTick();\n }\n\n function requestTick() {\n if (!ticking) {\n requestAnimationFrame(update);\n }\n ticking = true;\n }\n\n function update() {\n var trigger = title.getBoundingClientRect().top + window.scrollY;\n var triggerOffset = title.offsetHeight + 35;\n var progressMax = lastDocumentHeight - lastWindowHeight;\n\n // show/hide floating header\n if (lastScrollY >= trigger + triggerOffset) {\n header.classList.add('floating-active');\n } else {\n header.classList.remove('floating-active');\n }\n\n progressBar.setAttribute('max', progressMax);\n progressBar.setAttribute('value', lastScrollY);\n\n ticking = false;\n }\n\n window.addEventListener('scroll', onScroll, {passive: true});\n window.addEventListener('resize', onResize, false);\n\n update();\n };\n})(window, document);\n","/* eslint-env browser */\n\n/**\n * Gallery card support\n * Used on any individual post/page\n *\n * Detects when a gallery card has been used and applies sizing to make sure\n * the display matches what is seen in the editor.\n */\n\n(function (window, document) {\n var resizeImagesInGalleries = function resizeImagesInGalleries() {\n var images = document.querySelectorAll('.kg-gallery-image img');\n images.forEach(function (image) {\n var container = image.closest('.kg-gallery-image');\n var width = image.attributes.width.value;\n var height = image.attributes.height.value;\n var ratio = width / height;\n container.style.flex = ratio + ' 1 0%';\n });\n };\n\n document.addEventListener('DOMContentLoaded', resizeImagesInGalleries);\n})(window, document);\n","/* eslint-env browser */\n\n/**\n * Infinite Scroll\n * Used on all pages where there is a list of posts (homepage, tag index, etc).\n *\n * When the page is scrolled to 300px from the bottom, the next page of posts\n * is fetched by following the the that is output\n * by {{ghost_head}}.\n *\n * The individual post items are extracted from the fetched pages by looking for\n * a wrapper element with the class \"post-card\". Any found elements are appended\n * to the element with the class \"post-feed\" in the currently viewed page.\n */\n\n(function (window, document) {\n // next link element\n var nextElement = document.querySelector('link[rel=next]');\n if (!nextElement) {\n return;\n }\n\n // post feed element\n var feedElement = document.querySelector('.post-feed');\n if (!feedElement) {\n return;\n }\n\n var buffer = 300;\n\n var ticking = false;\n var loading = false;\n\n var lastScrollY = window.scrollY;\n var lastWindowHeight = window.innerHeight;\n var lastDocumentHeight = document.documentElement.scrollHeight;\n\n function onPageLoad() {\n if (this.status === 404) {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onResize);\n return;\n }\n\n // append contents\n var postElements = this.response.querySelectorAll('.post-card');\n postElements.forEach(function (item) {\n feedElement.appendChild(item);\n });\n\n // set next link\n var resNextElement = this.response.querySelector('link[rel=next]');\n if (resNextElement) {\n nextElement.href = resNextElement.href;\n } else {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onResize);\n }\n\n // sync status\n lastDocumentHeight = document.documentElement.scrollHeight;\n ticking = false;\n loading = false;\n }\n\n function onUpdate() {\n // return if already loading\n if (loading) {\n return;\n }\n\n // return if not scroll to the bottom\n if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {\n ticking = false;\n return;\n }\n\n loading = true;\n\n var xhr = new window.XMLHttpRequest();\n xhr.responseType = 'document';\n\n xhr.addEventListener('load', onPageLoad);\n\n xhr.open('GET', nextElement.href);\n xhr.send(null);\n }\n\n function requestTick() {\n ticking || window.requestAnimationFrame(onUpdate);\n ticking = true;\n }\n\n function onScroll() {\n lastScrollY = window.scrollY;\n requestTick();\n }\n\n function onResize() {\n lastWindowHeight = window.innerHeight;\n lastDocumentHeight = document.documentElement.scrollHeight;\n requestTick();\n }\n\n window.addEventListener('scroll', onScroll, {passive: true});\n window.addEventListener('resize', onResize);\n\n requestTick();\n})(window, document);\n"]} \ No newline at end of file diff --git a/assets/built/infinitescroll.js b/assets/built/infinitescroll.js deleted file mode 100644 index f45e86f..0000000 --- a/assets/built/infinitescroll.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(n,t){var r=t.querySelector("link[rel=next]");if(r){var i=t.querySelector(".post-feed");if(i){var o=300,s=!1,l=!1,c=n.scrollY,u=n.innerHeight,d=t.documentElement.scrollHeight;n.addEventListener("scroll",a,{passive:!0}),n.addEventListener("resize",m),f()}}function v(){if(404===this.status)return n.removeEventListener("scroll",a),void n.removeEventListener("resize",m);this.response.querySelectorAll(".post-card").forEach(function(e){i.appendChild(e)});var e=this.response.querySelector("link[rel=next]");e?r.href=e.href:(n.removeEventListener("scroll",a),n.removeEventListener("resize",m)),d=t.documentElement.scrollHeight,l=s=!1}function e(){if(!l)if(c+u<=d-o)s=!1;else{l=!0;var e=new n.XMLHttpRequest;e.responseType="document",e.addEventListener("load",v),e.open("GET",r.href),e.send(null)}}function f(){s||n.requestAnimationFrame(e),s=!0}function a(){c=n.scrollY,f()}function m(){u=n.innerHeight,d=t.documentElement.scrollHeight,f()}}(window,document); -//# sourceMappingURL=infinitescroll.js.map \ No newline at end of file diff --git a/assets/built/infinitescroll.js.map b/assets/built/infinitescroll.js.map deleted file mode 100644 index e14e6bc..0000000 --- a/assets/built/infinitescroll.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["infinitescroll.js"],"names":["window","document","nextElement","querySelector","feedElement","buffer","ticking","loading","lastScrollY","scrollY","lastWindowHeight","innerHeight","lastDocumentHeight","documentElement","scrollHeight","addEventListener","onScroll","passive","onResize","requestTick","onPageLoad","this","status","removeEventListener","response","querySelectorAll","forEach","item","appendChild","resNextElement","href","onUpdate","xhr","XMLHttpRequest","responseType","open","send","requestAnimationFrame"],"mappings":"CAIA,SAAUA,EAAQC,GAEd,IAAIC,EAAcD,EAASE,cAAc,kBACzC,GAAKD,EAAL,CAGA,IAAIE,EAAcH,EAASE,cAAc,cACzC,GAAKC,EAAL,CAEA,IAAIC,EAAS,IAETC,GAAU,EACVC,GAAU,EAEVC,EAAcR,EAAOS,QACrBC,EAAmBV,EAAOW,YAC1BC,EAAqBX,EAASY,gBAAgBC,aAmElDd,EAAOe,iBAAiB,SAAUC,EAAU,CAAEC,SAAS,IACvDjB,EAAOe,iBAAiB,SAAUG,GAElCC,KApEA,SAASC,IACL,GAAoB,MAAhBC,KAAKC,OAGL,OAFAtB,EAAOuB,oBAAoB,SAAUP,QACrChB,EAAOuB,oBAAoB,SAAUL,GAKtBG,KAAKG,SAASC,iBAAiB,cACrCC,QAAQ,SAAUC,GAC3BvB,EAAYwB,YAAYD,KAI5B,IAAIE,EAAiBR,KAAKG,SAASrB,cAAc,kBAC7C0B,EACA3B,EAAY4B,KAAOD,EAAeC,MAElC9B,EAAOuB,oBAAoB,SAAUP,GACrChB,EAAOuB,oBAAoB,SAAUL,IAIzCN,EAAqBX,EAASY,gBAAgBC,aAE9CP,EADAD,GAAU,EAId,SAASyB,IAEL,IAAIxB,EAGJ,GAAIC,EAAcE,GAAoBE,EAAqBP,EACvDC,GAAU,MADd,CAKAC,GAAU,EAEV,IAAIyB,EAAM,IAAIhC,EAAOiC,eACrBD,EAAIE,aAAe,WAEnBF,EAAIjB,iBAAiB,OAAQK,GAE7BY,EAAIG,KAAK,MAAOjC,EAAY4B,MAC5BE,EAAII,KAAK,OAGb,SAASjB,IACLb,GAAWN,EAAOqC,sBAAsBN,GACxCzB,GAAU,EAGd,SAASU,IACLR,EAAcR,EAAOS,QACrBU,IAGJ,SAASD,IACLR,EAAmBV,EAAOW,YAC1BC,EAAqBX,EAASY,gBAAgBC,aAC9CK,KAhFR,CAuFGnB,OAAQC","file":"infinitescroll.js","sourcesContent":["/**\n * Infinite Scroll\n */\n\n(function(window, document) {\n // next link element\n var nextElement = document.querySelector('link[rel=next]');\n if (!nextElement) return;\n\n // post feed element\n var feedElement = document.querySelector('.post-feed');\n if (!feedElement) return;\n\n var buffer = 300;\n\n var ticking = false;\n var loading = false;\n\n var lastScrollY = window.scrollY;\n var lastWindowHeight = window.innerHeight;\n var lastDocumentHeight = document.documentElement.scrollHeight;\n\n function onPageLoad() {\n if (this.status === 404) {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onResize);\n return;\n }\n\n // append contents\n var postElements = this.response.querySelectorAll('.post-card');\n postElements.forEach(function (item) {\n feedElement.appendChild(item);\n });\n\n // set next link\n var resNextElement = this.response.querySelector('link[rel=next]');\n if (resNextElement) {\n nextElement.href = resNextElement.href;\n } else {\n window.removeEventListener('scroll', onScroll);\n window.removeEventListener('resize', onResize);\n }\n\n // sync status\n lastDocumentHeight = document.documentElement.scrollHeight;\n ticking = false;\n loading = false;\n }\n\n function onUpdate() {\n // return if already loading\n if (loading) return;\n\n // return if not scroll to the bottom\n if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {\n ticking = false;\n return;\n }\n\n loading = true;\n\n var xhr = new window.XMLHttpRequest();\n xhr.responseType = 'document';\n\n xhr.addEventListener('load', onPageLoad);\n\n xhr.open('GET', nextElement.href);\n xhr.send(null);\n }\n\n function requestTick() {\n ticking || window.requestAnimationFrame(onUpdate);\n ticking = true;\n }\n\n function onScroll() {\n lastScrollY = window.scrollY;\n requestTick();\n }\n\n function onResize() {\n lastWindowHeight = window.innerHeight;\n lastDocumentHeight = document.documentElement.scrollHeight;\n requestTick();\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n window.addEventListener('resize', onResize);\n\n requestTick();\n})(window, document);\n"]} \ No newline at end of file diff --git a/assets/built/jquery.fitvids.js b/assets/built/jquery.fitvids.js deleted file mode 100644 index aa611f8..0000000 --- a/assets/built/jquery.fitvids.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(d){"use strict";d.fn.fitVids=function(t){var i={customSelector:null,ignore:null};if(!document.getElementById("fit-vids-style")){var e=document.head||document.getElementsByTagName("head")[0],r=document.createElement("div");r.innerHTML='

x

',e.appendChild(r.childNodes[1])}return t&&d.extend(i,t),this.each(function(){var t=['iframe[src*="player.vimeo.com"]','iframe[src*="youtube.com"]','iframe[src*="youtube-nocookie.com"]','iframe[src*="kickstarter.com"][src*="video.html"]',"object","embed"];i.customSelector&&t.push(i.customSelector);var r=".fitvidsignore";i.ignore&&(r=r+", "+i.ignore);var e=d(this).find(t.join(","));(e=(e=e.not("object object")).not(r)).each(function(){var t=d(this);if(!(0
').parent(".fluid-width-video-wrapper").css("padding-top",100*e+"%"),t.removeAttr("height").removeAttr("width")}})})},d.fn.fitVids._count=0}(window.jQuery||window.Zepto); -//# sourceMappingURL=jquery.fitvids.js.map \ No newline at end of file diff --git a/assets/built/jquery.fitvids.js.map b/assets/built/jquery.fitvids.js.map deleted file mode 100644 index c6e382c..0000000 --- a/assets/built/jquery.fitvids.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["jquery.fitvids.js"],"names":["$","fn","fitVids","options","settings","customSelector","ignore","document","getElementById","head","getElementsByTagName","div","createElement","innerHTML","appendChild","childNodes","extend","this","each","selectors","push","ignoreList","$allVideos","find","join","not","$this","parents","length","tagName","toLowerCase","parent","css","isNaN","attr","aspectRatio","parseInt","height","width","videoName","_count","wrap","removeAttr","window","jQuery","Zepto"],"mappings":"CAYC,SAAWA,GAEV,aAEAA,EAAEC,GAAGC,QAAU,SAAUC,GACvB,IAAIC,EAAW,CACbC,eAAgB,KAChBC,OAAQ,MAGV,IAAIC,SAASC,eAAe,kBAAmB,CAE7C,IAAIC,EAAOF,SAASE,MAAQF,SAASG,qBAAqB,QAAQ,GAE9DC,EAAMJ,SAASK,cAAc,OACjCD,EAAIE,UAAY,oUAChBJ,EAAKK,YAAYH,EAAII,WAAW,IAOlC,OAJKZ,GACHH,EAAEgB,OAAQZ,EAAUD,GAGfc,KAAKC,KAAK,WACf,IAAIC,EAAY,CACd,kCACA,6BACA,sCACA,oDACA,SACA,SAGEf,EAASC,gBACXc,EAAUC,KAAKhB,EAASC,gBAG1B,IAAIgB,EAAa,iBAEdjB,EAASE,SACVe,EAAaA,EAAa,KAAOjB,EAASE,QAG5C,IAAIgB,EAAatB,EAAEiB,MAAMM,KAAKJ,EAAUK,KAAK,OAE7CF,GADAA,EAAaA,EAAWG,IAAI,kBACJA,IAAIJ,IAEjBH,KAAK,WACd,IAAIQ,EAAQ1B,EAAEiB,MACd,KAAsC,EAAnCS,EAAMC,QAAQN,GAAYO,QAGM,UAA/BX,KAAKY,QAAQC,eAA6BJ,EAAMK,OAAO,UAAUH,QAAUF,EAAMK,OAAO,8BAA8BH,QAA1H,CACMF,EAAMM,IAAI,WAAcN,EAAMM,IAAI,WAAcC,MAAMP,EAAMQ,KAAK,aAAcD,MAAMP,EAAMQ,KAAK,YAEpGR,EAAMQ,KAAK,SAAU,GACrBR,EAAMQ,KAAK,QAAS,KAEtB,IAEIC,GAF0C,WAA/BlB,KAAKY,QAAQC,eAA+BJ,EAAMQ,KAAK,YAAcD,MAAMG,SAASV,EAAMQ,KAAK,UAAW,KAAUE,SAASV,EAAMQ,KAAK,UAAW,IAAMR,EAAMW,WACjKJ,MAAMG,SAASV,EAAMQ,KAAK,SAAU,KAA2CR,EAAMY,QAA1CF,SAASV,EAAMQ,KAAK,SAAU,KAEtF,IAAIR,EAAMQ,KAAK,QAAQ,CACrB,IAAIK,EAAY,SAAWvC,EAAEC,GAAGC,QAAQsC,OACxCd,EAAMQ,KAAK,OAAQK,GACnBvC,EAAEC,GAAGC,QAAQsC,SAEfd,EAAMe,KAAK,gGAAgGV,OAAO,8BAA8BC,IAAI,cAA8B,IAAdG,EAAmB,KACvLT,EAAMgB,WAAW,UAAUA,WAAW,eAM5C1C,EAAEC,GAAGC,QAAQsC,OAAS,EAzEvB,CA4EGG,OAAOC,QAAUD,OAAOE","file":"jquery.fitvids.js","sourcesContent":["/*jshint browser:true */\n/*!\n* FitVids 1.3\n*\n*\n* Copyright 2017, Chris Coyier + Dave Rupert + Ghost Foundation\n* This is an unofficial release, ported by John O'Nolan\n* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/\n* Released under the MIT license\n*\n*/\n\n;(function( $ ){\n\n 'use strict';\n\n $.fn.fitVids = function( options ) {\n var settings = {\n customSelector: null,\n ignore: null\n };\n\n if(!document.getElementById('fit-vids-style')) {\n // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js\n var head = document.head || document.getElementsByTagName('head')[0];\n var css = '.fluid-width-video-container{flex-grow: 1;width:100%;}.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';\n var div = document.createElement(\"div\");\n div.innerHTML = '

x

';\n head.appendChild(div.childNodes[1]);\n }\n\n if ( options ) {\n $.extend( settings, options );\n }\n\n return this.each(function(){\n var selectors = [\n 'iframe[src*=\"player.vimeo.com\"]',\n 'iframe[src*=\"youtube.com\"]',\n 'iframe[src*=\"youtube-nocookie.com\"]',\n 'iframe[src*=\"kickstarter.com\"][src*=\"video.html\"]',\n 'object',\n 'embed'\n ];\n\n if (settings.customSelector) {\n selectors.push(settings.customSelector);\n }\n\n var ignoreList = '.fitvidsignore';\n\n if(settings.ignore) {\n ignoreList = ignoreList + ', ' + settings.ignore;\n }\n\n var $allVideos = $(this).find(selectors.join(','));\n $allVideos = $allVideos.not('object object'); // SwfObj conflict patch\n $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.\n\n $allVideos.each(function(){\n var $this = $(this);\n if($this.parents(ignoreList).length > 0) {\n return; // Disable FitVids on this video.\n }\n if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }\n if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))\n {\n $this.attr('height', 9);\n $this.attr('width', 16);\n }\n var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),\n width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),\n aspectRatio = height / width;\n if(!$this.attr('name')){\n var videoName = 'fitvid' + $.fn.fitVids._count;\n $this.attr('name', videoName);\n $.fn.fitVids._count++;\n }\n $this.wrap('
').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');\n $this.removeAttr('height').removeAttr('width');\n });\n });\n };\n\n // Internal counter for unique video names.\n $.fn.fitVids._count = 0;\n\n// Works with either jQuery or Zepto\n})( window.jQuery || window.Zepto );\n"]} \ No newline at end of file diff --git a/assets/js/floating-header.js b/assets/js/floating-header.js new file mode 100644 index 0000000..b69646f --- /dev/null +++ b/assets/js/floating-header.js @@ -0,0 +1,73 @@ +/* eslint-env browser */ + +/** + * Floating header + * Used on invividual post pages, displays a sticky header with progress indicator + * + * This JS is automatically applied for any template where you use the + * {{> floating-header}} partial + */ + +(function (window, document) { + // set up Casper as a global object + if (!window.Casper) { + window.Casper = {}; + } + + window.Casper.floatingHeader = function floatingHeader() { + // NOTE: Scroll performance is poor in Safari + // - this appears to be due to the events firing much more slowly in Safari. + // Dropping the scroll event and using only a raf loop results in smoother + // scrolling but continuous processing even when not scrolling + + var progressBar = document.querySelector('#reading-progress'); + var header = document.querySelector('.floating-header'); + var title = document.querySelector('.post-full-title'); + + var lastScrollY = window.scrollY; + var lastWindowHeight = window.innerHeight; + var lastDocumentHeight = document.body.clientHeight; + var ticking = false; + + function onScroll() { + lastScrollY = window.scrollY; + requestTick(); + } + + function onResize() { + lastWindowHeight = window.innerHeight; + lastDocumentHeight = document.body.clientHeight; + requestTick(); + } + + function requestTick() { + if (!ticking) { + requestAnimationFrame(update); + } + ticking = true; + } + + function update() { + var trigger = title.getBoundingClientRect().top + window.scrollY; + var triggerOffset = title.offsetHeight + 35; + var progressMax = lastDocumentHeight - lastWindowHeight; + + // show/hide floating header + if (lastScrollY >= trigger + triggerOffset) { + header.classList.add('floating-active'); + } else { + header.classList.remove('floating-active'); + } + + progressBar.setAttribute('max', progressMax); + progressBar.setAttribute('value', lastScrollY); + + ticking = false; + } + + window.addEventListener('scroll', onScroll, {passive: true}); + window.addEventListener('resize', onResize, false); + + update(); + }; +})(window, document); diff --git a/assets/js/gallery-card.js b/assets/js/gallery-card.js new file mode 100644 index 0000000..fa630cc --- /dev/null +++ b/assets/js/gallery-card.js @@ -0,0 +1,24 @@ +/* eslint-env browser */ + +/** + * Gallery card support + * Used on any individual post/page + * + * Detects when a gallery card has been used and applies sizing to make sure + * the display matches what is seen in the editor. + */ + +(function (window, document) { + var resizeImagesInGalleries = function resizeImagesInGalleries() { + var images = document.querySelectorAll('.kg-gallery-image img'); + images.forEach(function (image) { + var container = image.closest('.kg-gallery-image'); + var width = image.attributes.width.value; + var height = image.attributes.height.value; + var ratio = width / height; + container.style.flex = ratio + ' 1 0%'; + }); + }; + + document.addEventListener('DOMContentLoaded', resizeImagesInGalleries); +})(window, document); diff --git a/assets/js/infinitescroll.js b/assets/js/infinitescroll.js index fc1e80b..6b0ec99 100644 --- a/assets/js/infinitescroll.js +++ b/assets/js/infinitescroll.js @@ -1,15 +1,30 @@ +/* eslint-env browser */ + /** * Infinite Scroll + * Used on all pages where there is a list of posts (homepage, tag index, etc). + * + * When the page is scrolled to 300px from the bottom, the next page of posts + * is fetched by following the the that is output + * by {{ghost_head}}. + * + * The individual post items are extracted from the fetched pages by looking for + * a wrapper element with the class "post-card". Any found elements are appended + * to the element with the class "post-feed" in the currently viewed page. */ -(function(window, document) { +(function (window, document) { // next link element var nextElement = document.querySelector('link[rel=next]'); - if (!nextElement) return; + if (!nextElement) { + return; + } // post feed element var feedElement = document.querySelector('.post-feed'); - if (!feedElement) return; + if (!feedElement) { + return; + } var buffer = 300; @@ -50,7 +65,9 @@ function onUpdate() { // return if already loading - if (loading) return; + if (loading) { + return; + } // return if not scroll to the bottom if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) { @@ -85,7 +102,7 @@ requestTick(); } - window.addEventListener('scroll', onScroll, { passive: true }); + window.addEventListener('scroll', onScroll, {passive: true}); window.addEventListener('resize', onResize); requestTick(); diff --git a/assets/js/jquery.fitvids.js b/assets/js/lib/jquery.fitvids.js similarity index 100% rename from assets/js/jquery.fitvids.js rename to assets/js/lib/jquery.fitvids.js diff --git a/default.hbs b/default.hbs index ef888e7..7e953dd 100644 --- a/default.hbs +++ b/default.hbs @@ -55,27 +55,14 @@ {{/if}} - - - - {{!-- jQuery + Fitvids, which makes all video embeds responsive --}} + {{!-- jQuery, required for fitvids --}} - - - + {{!-- Fitvids (for responsive video embeds), infinite scroll, floating header, and gallery card support --}} + {{!-- The #block helper will pull in data from the #contentFor other template files. In this case, there's some JavaScript which we only want to use in post.hbs, but it needs to be included down here, after jQuery has already loaded. --}} {{{block "scripts"}}} diff --git a/gulpfile.js b/gulpfile.js index e19cbf7..87af890 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -5,6 +5,7 @@ const pump = require('pump'); const livereload = require('gulp-livereload'); const postcss = require('gulp-postcss'); const zip = require('gulp-zip'); +const concat = require('gulp-concat'); const uglify = require('gulp-uglify'); const beeper = require('beeper'); const fs = require('fs'); @@ -56,7 +57,12 @@ function css(done) { function js(done) { pump([ - src('assets/js/*.js', {sourcemaps: true}), + src([ + // pull in lib files first so our own code can depend on it + 'assets/js/lib/*.js', + 'assets/js/*.js' + ], {sourcemaps: true}), + concat('casper.js'), uglify(), dest('assets/built/', {sourcemaps: '.'}), livereload() diff --git a/package.json b/package.json index eb3f404..ddaa114 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "cssnano": "4.1.10", "gscan": "3.0.0", "gulp": "4.0.2", + "gulp-concat": "^2.6.1", "gulp-livereload": "4.0.2", "gulp-postcss": "8.0.0", "gulp-uglify": "3.0.2", diff --git a/page.hbs b/page.hbs index 95f9059..20fefa7 100644 --- a/page.hbs +++ b/page.hbs @@ -55,9 +55,9 @@ into the {body} of the default.hbs template --}} {{!-- The #contentFor helper here will send everything inside it up to the matching #block helper found in default.hbs --}} {{#contentFor "scripts"}} {{/contentFor}} diff --git a/partials/floating-header.hbs b/partials/floating-header.hbs index 36eedd7..c77c58a 100644 --- a/partials/floating-header.hbs +++ b/partials/floating-header.hbs @@ -26,3 +26,11 @@ + +{{#contentFor "scripts"}} + +{{/contentFor}} \ No newline at end of file diff --git a/post.hbs b/post.hbs index f58e0b4..974311c 100644 --- a/post.hbs +++ b/post.hbs @@ -145,67 +145,9 @@ into the {body} of the default.hbs template --}} {{!-- The #contentFor helper here will send everything inside it up to the matching #block helper found in default.hbs --}} {{#contentFor "scripts"}} {{/contentFor}} diff --git a/yarn.lock b/yarn.lock index a33812e..03605db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -674,6 +674,13 @@ concat-stream@^1.5.2, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +concat-with-sourcemaps@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e" + integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg== + dependencies: + source-map "^0.6.1" + config-chain@~1.1.5: version "1.1.12" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" @@ -1672,6 +1679,15 @@ gulp-cli@^2.2.0: v8flags "^3.0.1" yargs "^7.1.0" +gulp-concat@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/gulp-concat/-/gulp-concat-2.6.1.tgz#633d16c95d88504628ad02665663cee5a4793353" + integrity sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M= + dependencies: + concat-with-sourcemaps "^1.0.0" + through2 "^2.0.0" + vinyl "^2.0.0" + gulp-livereload@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/gulp-livereload/-/gulp-livereload-4.0.2.tgz#fc8a75c7511cd65afd2202cbcdc8bb0f8dde377b"