diff --git a/assets/_src/js/_faq.js b/assets/_src/js/_faq.js
new file mode 100644
index 0000000..7d93797
--- /dev/null
+++ b/assets/_src/js/_faq.js
@@ -0,0 +1,63 @@
+
+//=include vendor/toc.js
+//=include vendor/affix.js
+
+var Faq = (function(w, d, $) {
+
+ 'use strict'
+
+ var app, _private, _config
+
+ _config = {
+ faqQuestion: $('.faq__question'),
+ faqAnswer: $('.faq__answer'),
+ faqTitle: $('.faq__title'),
+ faqTocColumn: $('.grid__col--toc'),
+ faqToc: $('#toc'),
+ minWidth: 768 // $screen-sm
+ }
+
+ _private = {
+ faqToggle: function() {
+ _config.faqQuestion.click(function() {
+ $(this).toggleClass('open');
+ $(this).next(_config.faqAnswer).toggleClass('open');
+ });
+ },
+ faqTocInit: function() {
+ _config.faqToc.toc({
+ 'selectors': _config.faqTitle, // elements to use as headings
+ 'container': 'body', // element to find all selectors in
+ 'highlightOffset': 100, // offset to trigger the next headline
+ });
+ },
+ faqTocSticky: function() {
+ var win = $(window);
+
+ win.on('load resize',function(e) {
+ if (_private.isWide()) {
+ _config.faqToc.affix({
+ offset: {
+ top: ( _config.faqTocColumn.offset().top + 20 ),
+ bottom: ( $('.section-faq:last-child').outerHeight(true) + 40 )
+ }
+ });
+ }
+ });
+ },
+ isWide: function() {
+ return $(window).width() >= _config.minWidth;
+ }
+ }
+
+ app = {
+ init: function() {
+ _private.faqToggle();
+ _private.faqTocInit();
+ _private.faqTocSticky();
+ }
+ }
+
+ return app
+
+})(window, document, jQuery)
diff --git a/assets/_src/js/ascribe.js b/assets/_src/js/ascribe.js
index 0d2ca34..66ff5b2 100644
--- a/assets/_src/js/ascribe.js
+++ b/assets/_src/js/ascribe.js
@@ -1,8 +1,11 @@
+//=include _faq.js
+
$(document).ready(function(){
+ Faq.init();
+
slider();
- featuredFAQ();
marketplaces();
tourNav();
mobileNav();
@@ -39,11 +42,7 @@ $(document).ready(function(){
});
}
- function featuredFAQ() {
- $('.featured-faqs dt').click(function() {
- $(this).next('dd').toggleClass('open');
- });
- }
+
function marketplaces() {
$('.top-tab').click(function(){
$('.top-tab').removeClass('active');
diff --git a/assets/_src/js/vendor/affix.js b/assets/_src/js/vendor/affix.js
new file mode 100644
index 0000000..b1d8d2c
--- /dev/null
+++ b/assets/_src/js/vendor/affix.js
@@ -0,0 +1,162 @@
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.6
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // AFFIX CLASS DEFINITION
+ // ======================
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options)
+
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
+
+ this.$element = $(element)
+ this.affixed = null
+ this.unpin = null
+ this.pinnedOffset = null
+
+ this.checkPosition()
+ }
+
+ Affix.VERSION = '3.3.6'
+
+ Affix.RESET = 'affix affix-top affix-bottom'
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && scrollTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset
+ this.$element.removeClass(Affix.RESET).addClass('affix')
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ return (this.pinnedOffset = position.top - scrollTop)
+ }
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = Math.max($(document).height(), $(document.body).height())
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '')
+
+ var affixType = 'affix' + (affix ? '-' + affix : '')
+ var e = $.Event(affixType + '.bs.affix')
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
+ }
+ }
+
+
+ // AFFIX PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.affix')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.affix
+
+ $.fn.affix = Plugin
+ $.fn.affix.Constructor = Affix
+
+
+ // AFFIX NO CONFLICT
+ // =================
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
+
+
+ // AFFIX DATA-API
+ // ==============
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ var data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
diff --git a/assets/_src/js/vendor/toc.js b/assets/_src/js/vendor/toc.js
new file mode 100644
index 0000000..cef6942
--- /dev/null
+++ b/assets/_src/js/vendor/toc.js
@@ -0,0 +1,197 @@
+/*!
+ * toc - jQuery Table of Contents Plugin
+ * v0.3.2
+ * http://projects.jga.me/toc/
+ * copyright Greg Allen 2014
+ * MIT License
+ */
+/*!
+ * smooth-scroller - Javascript lib to handle smooth scrolling
+ * v0.1.2
+ * https://github.com/firstandthird/smooth-scroller
+ * copyright First+Third 2014
+ * MIT License
+ */
+//smooth-scroller.js
+
+(function($) {
+ $.fn.smoothScroller = function(options) {
+ options = $.extend({}, $.fn.smoothScroller.defaults, options);
+ var el = $(this);
+
+ $(options.scrollEl).animate({
+ scrollTop: el.offset().top - $(options.scrollEl).offset().top - options.offset
+ }, options.speed, options.ease, function() {
+ var hash = el.attr('id');
+
+ if (hash.length) {
+ document.location.hash = hash;
+ }
+
+ el.trigger('smoothScrollerComplete');
+ });
+
+ return this;
+ };
+
+ $.fn.smoothScroller.defaults = {
+ speed: 400,
+ ease: 'swing',
+ scrollEl: 'body,html',
+ offset: 0
+ };
+
+ $('body').on('click', '[data-smoothscroller]', function(e) {
+ e.preventDefault();
+ var href = $(this).attr('href');
+
+ if (href.indexOf('#') === 0) {
+ $(href).smoothScroller();
+ }
+ });
+}(jQuery));
+
+(function($) {
+ var verboseIdCache = {};
+ $.fn.toc = function(options) {
+ var self = this;
+ var opts = $.extend({}, jQuery.fn.toc.defaults, options);
+
+ var container = $(opts.container);
+ var headings = $(opts.selectors, container);
+ var activeClassName = opts.activeClass;
+
+ var headingOffsets = function() {
+ var offsets = [];
+ headings.each(function(i, heading) {
+ var $h = $(heading);
+ offsets.push($h.offset().top - opts.highlightOffset);
+ });
+ return offsets;
+ };
+
+ var scrollTo = function(e, callback) {
+ if (opts.smoothScrolling && typeof opts.smoothScrolling === 'function') {
+ e.preventDefault();
+ var elScrollTo = $(e.target).attr('href');
+
+ opts.smoothScrolling(elScrollTo, opts, callback);
+ }
+ $('li', self).removeClass(activeClassName);
+ $(e.target).parent().addClass(activeClassName);
+ };
+
+ //highlight on scroll
+ var timeout;
+ var highlightOnScroll = function(e) {
+ if (timeout) {
+ clearTimeout(timeout);
+ }
+ timeout = setTimeout(function() {
+ var top = $(window).scrollTop(),
+ highlighted, closest = Number.MAX_VALUE,
+ index = 0
+ offsets = headingOffsets();
+
+ for (var i = 0, c = offsets.length; i < c; i++) {
+ var currentClosest = Math.abs(offsets[i] - top);
+ if (currentClosest < closest) {
+ index = i;
+ closest = currentClosest;
+ }
+ }
+
+ $('li', self).removeClass(activeClassName);
+ highlighted = $('li:eq(' + index + ')', self).addClass(activeClassName);
+ opts.onHighlight(highlighted);
+ }, 50);
+ };
+ if (opts.highlightOnScroll) {
+ $(window).bind('scroll', highlightOnScroll);
+ highlightOnScroll();
+ }
+
+ return this.each(function() {
+ //build TOC
+ var el = $(this);
+ var ul = $(opts.listType);
+
+ headings.each(function(i, heading) {
+ var $h = $(heading);
+
+ var anchorName = opts.anchorName(i, heading, opts.prefix);
+
+ //add anchor
+ if (heading.id !== anchorName) {
+ var anchor = $('').attr('id', anchorName).insertBefore($h);
+ }
+
+ //build TOC item
+ var a = $('')
+ .text(opts.headerText(i, heading, $h))
+ .attr('href', '#' + anchorName)
+ .bind('click', function(e) {
+ $(window).unbind('scroll', highlightOnScroll);
+ scrollTo(e, function() {
+ $(window).bind('scroll', highlightOnScroll);
+ });
+ el.trigger('selected', $(this).attr('href'));
+ });
+
+ var li = $('
')
+ .addClass(opts.itemClass(i, heading, $h, opts.prefix))
+ .append(a);
+
+ ul.append(li);
+ });
+ el.html(ul);
+ });
+ };
+
+
+ jQuery.fn.toc.defaults = {
+ container: 'body',
+ listType: '',
+ selectors: 'h1,h2,h3',
+ smoothScrolling: function(target, options, callback) {
+ $(target).smoothScroller({
+ offset: options.scrollToOffset
+ }).on('smoothScrollerComplete', function() {
+ callback();
+ });
+ },
+ scrollToOffset: 0,
+ prefix: 'toc',
+ activeClass: 'toc-active',
+ onHighlight: function() {},
+ highlightOnScroll: true,
+ highlightOffset: 100,
+ anchorName: function(i, heading, prefix) {
+ if (heading.id.length) {
+ return heading.id;
+ }
+
+ var candidateId = $(heading).text().replace(/[^a-z0-9]/ig, ' ').replace(/\s+/g, '-').toLowerCase();
+ if (verboseIdCache[candidateId]) {
+ var j = 2;
+
+ while (verboseIdCache[candidateId + j]) {
+ j++;
+ }
+ candidateId = candidateId + '-' + j;
+
+ }
+ verboseIdCache[candidateId] = true;
+
+ return prefix + '-' + candidateId;
+ },
+ headerText: function(i, heading, $heading) {
+ return $heading.text();
+ },
+ itemClass: function(i, heading, $heading, prefix) {
+ return prefix + '-' + $heading[0].tagName.toLowerCase();
+ }
+
+ };
+
+})(jQuery);
diff --git a/assets/_src/less/ascribe.less b/assets/_src/less/ascribe.less
index 8fff20c..1dc9095 100644
--- a/assets/_src/less/ascribe.less
+++ b/assets/_src/less/ascribe.less
@@ -31,6 +31,7 @@
@import 'ascribe/_team.less';
@import 'ascribe/_blog.less';
@import 'ascribe/_testimonials.less';
+@import 'ascribe/_faq.less';
@import '_page-api.less';
@@ -372,45 +373,6 @@
}
}
-.faq {
-
- > h1 { margin-top: 0; }
-
- dl,dt,dd {
- margin: 0;
- padding: 0;
- }
-
- dd:not(:last-child) {
- margin-bottom: @spacer;
- }
-
- dt {
- &:extend(.bold);
- }
-
- .featured-faqs {
-
- dt {
- color: @pink;
- cursor: pointer;
- }
- dd {
- max-height:0;
- overflow-y:hidden;
- transition: .2s ease-out;
- margin-bottom: @spacer;
-
- &.open {
- max-height: 800px;
- }
- }
- }
- .regular-faqs {
-
- }
-}
-
.values {
padding-bottom: @spacer;
diff --git a/assets/_src/less/ascribe/_faq.less b/assets/_src/less/ascribe/_faq.less
new file mode 100644
index 0000000..d953aaa
--- /dev/null
+++ b/assets/_src/less/ascribe/_faq.less
@@ -0,0 +1,156 @@
+
+.section-faq {
+ padding-top: @spacer;
+ padding-bottom: @spacer;
+}
+
+.faq {
+ margin-left: 20px;
+}
+
+
+//
+// FAQ Section Title
+//
+.faq__title {
+ &:extend(.h2);
+ margin-top: 0;
+}
+
+
+//
+// FAQ Question
+//
+.faq__question {
+ &:extend(.bold);
+ display: block;
+ margin-top: 0;
+ margin-bottom: (@spacer / 2);
+ cursor: pointer;
+
+ .caret {
+ margin-left: -20px;
+ margin-right: 10px;
+ }
+
+ &.open .caret {
+ transform: rotate(90deg);
+ }
+}
+
+
+//
+// FAQ Answer
+//
+.faq__answer {
+ transition: .2s ease-out;
+ transform-origin: top;
+ height: 0;
+ overflow: hidden;
+ margin-left: 0;
+
+ &.open {
+ animation: openQuestion .15s ease-out forwards;
+ }
+}
+
+@keyframes openQuestion {
+ 0% {
+ transform: scaleY(0);
+ opacity: 0;
+ }
+ 100% {
+ transform: scaleY(1);
+ opacity: 1;
+ height: 100%;
+ }
+}
+
+
+//
+// Featured FAQ modifier
+//
+.faq--featured {
+ .faq__question {
+ color: @pink;
+ }
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-width: 5px 0 5px 6px;
+ border-color: transparent transparent transparent @greySocial;
+ transition: .15s ease-out;
+}
+
+.grid__col--toc {
+ position: relative;
+
+ @media (@screen-sm) {
+ flex: 0 0 33% !important;
+ }
+}
+
+
+//
+// Table of Contents
+//
+#toc {
+ margin-top: @spacer;
+
+ &.affix {
+ top: 0;
+ padding-top: @spacer;
+ }
+
+ ul {
+ &:extend(.list-unstyled all);
+
+ li,
+ a {
+ line-height: @line-height-base;
+ }
+
+ li {
+ display: inline-block;
+
+ @media (@screen-sm) {
+ display: block;
+ }
+ }
+
+ a {
+ &:extend(.h4);
+ color: @link-color;
+ display: block;
+ margin: 0;
+ padding: 8px 12px;
+
+ @media (@screen-sm) {
+ padding: 6px 0;
+ }
+
+ &:active,
+ &:focus {
+ outline: 0;
+ }
+ }
+
+ a:hover,
+ a:focus,
+ .toc-active a {
+ color: @link-hover-color;
+ }
+ }
+}
+
+
+//
+// Affix.js helpers
+//
+.affix {
+ position: fixed !important;
+}
diff --git a/assets/_src/less/ascribe/_typography.less b/assets/_src/less/ascribe/_typography.less
index 7c138cc..f52a52a 100644
--- a/assets/_src/less/ascribe/_typography.less
+++ b/assets/_src/less/ascribe/_typography.less
@@ -105,6 +105,11 @@ h1, h2, h3, h4, h5, h6,
color: @black;
}
+.page-title {
+ margin-top: 0;
+ text-align: center;
+}
+
// Reset fonts for relevant elements
diff --git a/content-main.php b/content-main.php
index b52fb41..3a8bbbc 100644
--- a/content-main.php
+++ b/content-main.php
@@ -1,4 +1,26 @@
-
- loopSubtemplates(); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ loopSubtemplates(); ?>
+
+
+
+ loopSubtemplates();
+
+ } ?>
+
diff --git a/controller/classes/Subtemplate.php b/controller/classes/Subtemplate.php
index 8b7f3ab..4d1164b 100644
--- a/controller/classes/Subtemplate.php
+++ b/controller/classes/Subtemplate.php
@@ -664,43 +664,63 @@ class Subtemplate {
return $result;
}
+
+
+ //
+ // Subtemplate: FAQs
+ //
public function faq($subtemplateTitle) {
- $featuredFAQ = '
';
+
+ $featuredFAQ = '';
+ $regularFAQ = '';
+
if (have_rows('featured_faqs')) {
+
+ $featuredFAQ = '';
+
while (have_rows('featured_faqs')) {
the_row();
- $question = get_sub_field('question');
- $answer = get_sub_field('answer');
+ $question = get_sub_field('question');
+ $answer = get_sub_field('answer');
- $featuredFAQ .= "- {$question}
- - {$answer}
";
+ $featuredFAQ .= "- {$question}
+ - {$answer}
";
}
- }
- $featuredFAQ .= "
";
- $regularFAQ = '';
+ $featuredFAQ .= "
";
+ }
+
if (have_rows('regular_faqs')) {
+
+ $regularFAQ = '';
+
while (have_rows('regular_faqs')) {
the_row();
- $question = get_sub_field('question');
- $answer = get_sub_field('answer');
+ $question = get_sub_field('question');
+ $answer = get_sub_field('answer');
- $regularFAQ .= "- Q: {$question}
- - A: {$answer}
";
+ $regularFAQ .= "- {$question}
+ - {$answer}
";
}
- }
- $regularFAQ .= "
";
- $result = "
- {$subtemplateTitle}
+ $regularFAQ .= "
";
+ }
+
+ // create ID for section jumps from lowercased & sanitized title
+ $subtemplateTitleID = strtolower(sanitize_html_class($subtemplateTitle));
+
+ $result = "
+ {$subtemplateTitle}
{$featuredFAQ}
{$regularFAQ}
";
return $result;
}
+
+
public function values($subtemplateTitle) {
$values = '';
if (have_rows('ascribe_values')) {
@@ -724,6 +744,8 @@ class Subtemplate {
return $result;
}
+
+
public function careers($subtemplateTitle) {
$args = array(
'post_type' => 'career',
@@ -752,6 +774,8 @@ class Subtemplate {
return $result;
}
+
+
public function mediaDetail($subtemplateTitle) {
$image = get_sub_field('image')['url'];
diff --git a/package.json b/package.json
index 31e84e0..899bc1b 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,8 @@
},
"dependencies": {
"normalize-css": ">=2.3.1",
- "normalize-opentype.css": ">=0.2.4"
+ "normalize-opentype.css": ">=0.2.4",
+ "toc": "jgallen23/toc"
},
"devDependencies": {
"browser-sync": "^2.10.0",