<section class="accordion">
<div class="accordion-tablist" role="tablist">
<div class="accordion-tab">
<a id="year-one-label" href="#year-one" class="accordion-tab-title-container collapse-toggle active" data-collapse role="tab" aria-expanded="true" aria-controls="year-one">
<h4 class="accordion-tab-title">
Year one with a really long heading
<span class="accordion-tab-title-indicator">
<i class="uod-icons uod-icons-chevron-down"></i>
</span>
</h4>
</a>
<div id="year-one" class="accordion-tab-content collapse active" role="tabpanel" aria-labelledby="year-one-label">
<div class="accordion-tab-content-inner">
You’ll study modules such as:
<ol>
<li>Making it: Materials and Manufacturing Processes</li>
<li>Product Design Studies</li>
<li>Innovation</li>
<li>Computer Aided Product Design</li>
<li>Design Evaluation</li>
<li>Context: Being a Product Designer</li>
</ol>
</div>
</div>
</div>
<div class="accordion-tab">
<a id="year-two-label" href="#year-two" class="accordion-tab-title-container collapse-toggle" data-collapse role="tab" aria-expanded="false" aria-controls="year-two">
<h4 class="accordion-tab-title">
Year two with an even longer (maybe) heading
<span class="accordion-tab-title-indicator">
<i class="uod-icons uod-icons-chevron-down"></i>
</span>
</h4>
</a>
<div id="year-two" class="accordion-tab-content collapse" role="tabpanel" aria-labelledby="year-two-label">
<div class="accordion-tab-content-inner">
<p>Product Design at Derby is aimed at creative people who may have studied Art and Design or Design Technology at school or developed a passion for the subject since leaving formal education. We will help you to
<strong>build on your creativity</strong> and develop an understanding of the
<em>reality of design</em> for manufacture.
<a href="#">This is a link.</a> because we teach in small groups we can help you to develop your potential as an individual and support your enthusiasm for design.</p>
</div>
</div>
</div>
<div class="accordion-tab">
<a id="year-three-label" href="#year-three" class="accordion-tab-title-container collapse-toggle" data-collapse role="tab" aria-expanded="false" aria-controls="year-three">
<h4 class="accordion-tab-title">
Year three
<span class="accordion-tab-title-indicator">
<i class="uod-icons uod-icons-chevron-down"></i>
</span>
</h4>
</a>
<div id="year-three" class="accordion-tab-content collapse" role="tabpanel" aria-labelledby="year-three-label">
<div class="accordion-tab-content-inner">
<p>Full-time students applying in September should apply for this course through UCAS or you can apply directly to the University for an undergraduate course if you’re not applying to any other UK university in the same year.</p>
<p>
<a href="#" class="button-outline">
Apply through UCAS<i class="uod-icons uod-icons-external-link"></i>
</a>
<a href="#" class="button-outline">
Apply directly to the University<i class="uod-icons uod-icons-external-link"></i>
</a>
</p>
</div>
</div>
</div>
</div>
</section>
<style type="text/css">
#udol-course-taster-exercise .accordion-tab:after {
display: inline-block;
transform: translate(0, 0);
text-rendering: auto;
font: normal normal 400 14px/1 uod-icons;
font-size: inherit;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
content: "\ea0d";
font-size: 2em;
color: #101d49;
width: 100%;
text-align: center;
padding-top: 20px;
}
#udol-course-taster-exercise .accordion-tab:last-child:after {
content: '';
padding-top: 0;
}
</style>
<section class="accordion{% if fullWidth == true %} full-width{% endif %}{% if scheme %} accordion-scheme-{{ scheme }}{% endif %}"{% if id %} id="{{ id|raw }}"{% endif %}>
{% if title %}<h2 id="{% if id %}{{ id }}{% else %}{{ title | lower | replace({ ' ' : '-' }) }}{% endif %}" class="accordion-title">{{ title|raw }}</h2>{% endif %}
{% if intro %}<p class="accordion-intro">{{ intro|raw }}</p>{% endif %}
<div class="accordion-tablist" role="tablist">
{% for item in contents %}
<div class="accordion-tab">
<a id="{{ item.tag|raw }}-label" href="#{{ item.tag|raw }}" class="accordion-tab-title-container collapse-toggle{{ item.expanded == true ? ' active'}}{% if usehash == true %} usehash{% endif %}"
data-collapse {% if modal == true %} data-group="{{ tag|raw }}" {% endif %}
role="tab" aria-expanded="{{ item.expanded == true ? 'true' : 'false' }}" aria-controls="{{ item.tag|raw }}">
{% if useDivTitles %}
<div class="accordion-tab-title h4">
{{ item.label|raw }}
<span class="accordion-tab-title-indicator">
<i class="uod-icons uod-icons-chevron-down"></i>
</span>
</div>
{% else %}
<h4 class="accordion-tab-title">
{{ item.label|raw }}
<span class="accordion-tab-title-indicator">
<i class="uod-icons uod-icons-chevron-down"></i>
</span>
</h4>
{% endif %}
</a>
<div id="{{ item.tag|raw }}" class="accordion-tab-content collapse{{ item.expanded == true ? ' active'}}" role="tabpanel" aria-labelledby="{{ item.tag|raw }}-label">
<div class="accordion-tab-content-inner">
{{ item.content|raw }}
</div>
</div>
</div>
{% endfor %}
</div>
</section>
<style type="text/css">
#udol-course-taster-exercise .accordion-tab:after {
display: inline-block;
transform: translate(0, 0);
text-rendering: auto;
font: normal normal 400 14px/1 uod-icons;
font-size: inherit;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
content: "\ea0d";
font-size: 2em;
color: #101d49;
width: 100%;
text-align: center;
padding-top: 20px;
}
#udol-course-taster-exercise .accordion-tab:last-child:after {
content: '';
padding-top: 0;
}
</style>
{
"contents": [
{
"tag": "year-one",
"label": "Year one with a really long heading",
"expanded": true,
"content": "You’ll study modules such as:\n <ol>\n <li>Making it: Materials and Manufacturing Processes</li>\n <li>Product Design Studies</li>\n <li>Innovation</li>\n <li>Computer Aided Product Design</li>\n <li>Design Evaluation</li>\n <li>Context: Being a Product Designer</li>\n </ol>"
},
{
"tag": "year-two",
"label": "Year two with an even longer (maybe) heading",
"expanded": null,
"content": "<p>Product Design at Derby is aimed at creative people who may have studied Art and Design or Design Technology\n at school or developed a passion for the subject since leaving formal education. We will help you to\n <strong>build on your creativity</strong> and develop an understanding of the\n <em>reality of design</em> for manufacture.\n <a href=\"#\">This is a link.</a> because we teach in small groups we can help you to develop your potential as an\n individual and support your enthusiasm for design.</p>"
},
{
"tag": "year-three",
"label": "Year three",
"expanded": null,
"content": "<p>Full-time students applying in September should apply for this course through UCAS or you can apply directly to the University for an undergraduate course if you’re not applying to any other UK university in the same year.</p>\n <p>\n <a href=\"#\" class=\"button-outline\">\n Apply through UCAS<i class=\"uod-icons uod-icons-external-link\"></i>\n </a>\n <a href=\"#\" class=\"button-outline\">\n Apply directly to the University<i class=\"uod-icons uod-icons-external-link\"></i>\n </a>\n </p>"
}
]
}
import houdini from './houdini.custom'
/**
* Polyfil this function (swapping out for jquery long term would be nice)
*/
const forEach = function (array, callback, scope) {
for (let i = 0; i < array.length; i++) {
callback.call(scope, i, array[i]);
}
};
/**
* Custom Events
*/
const ACCORDION_OPEN = 'ACCORDION_OPEN'
const ACCORDION_CLOSE = 'ACCORDION_CLOSE'
/**
* When the page hash changes, scroll to that position.
*/
function scrollIntoView() {
const hash = window.location.hash;
if (!hash) {
return;
}
var toggle = document.querySelector(hash + '-label');
if (toggle) {
window.scrollTo(0, toggle.offsetTop);
}
}
const accordionElementExistsOnPage = document.querySelector('.accordion') != undefined;
if (accordionElementExistsOnPage) {
const hash = window.location.hash;
if (hash) {
// auto-close any open panels which do not match the current hash
const toggle = document.querySelectorAll('[data-collapse]' + ':not([href*="' + hash + '"])');
forEach(toggle, function (index, value) {
value.classList.remove('active');
value.setAttribute('aria-expanded', 'false');
const elementId = value.getAttribute('aria-controls');
const content = document.querySelector('[id="' + elementId + '"]');
if (content) {
content.classList.remove('active');
}
});
}
window.addEventListener('hashchange', scrollIntoView, false);
houdini.init({
callbackOpen: function (content, toggle) {
// remove the focus rect created by houdinijs forcing focus to the new panel
content.blur();
// set a new max-height to the content height (max height can be animaed, height alone cannot)
content.style['max-height'] = content.scrollHeight + 'px';
if (toggle) {
// update the aria metadata for this component to reflect the new state
toggle.setAttribute('aria-expanded', 'true');
// dispatch a custom event to allow other components to react to the panel being opened
$('.main-navigation-mobile').trigger(ACCORDION_OPEN, toggle.getAttribute('aria-controls'));
}
},
callbackClose: function (content, toggle) {
// set a new max-height to allow the panel to be animated closed
content.style['max-height'] = 0;
if (toggle) {
// if the hash is currently in the url and we've just closed the panel, remove the hash
if (toggle.getAttribute('aria-expanded') == 'true' && '#' + toggle.getAttribute('aria-controls') === window.location.hash) {
history.pushState("", document.title, window.location.pathname + window.location.search);
}
// update the aria metadata for this component to reflect the new state
toggle.setAttribute('aria-expanded', 'false');
// remove the focus rect created by houdinijs forcing focus to the new panel
toggle.blur();
// dispatch a custom event to allow other components to react to the panel being closed
$('.main-navigation-mobile').trigger(ACCORDION_CLOSE, toggle.getAttribute('aria-controls'));
} else {
// dispatch a custom event to allow other components to react to the panel being closed
$('.main-navigation-mobile').trigger(ACCORDION_CLOSE);
}
}
});
}
.accordion-tab {
margin-bottom: $margin-extra-small;
&-title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0;
.full-width & {
@include full-bleed-inset;
}
&-container {
@include disable-underlines;
display: block;
transition: background-color .3s $default-animation-curve;
border-radius: 2px;
background: $light-grey;
padding: 13px 60px 13px 10px;
@include for-tablet-portrait-up {
padding: 15.5px 65px 15.5px 20px;
}
.full-width & {
padding-right: 0;
padding-left: 0;
}
.accordion-scheme-dark & {
background-color: #191919;
}
&:hover,
&:focus,
&:active {
background-color: $light-grey-hover;
.accordion-scheme-dark & {
background-color: $text-black;
}
}
}
&-indicator {
display: inline-block;
position: absolute;
top: 50%;
right: 10px;
margin-top: -20px;
margin-left: 10px;
border: solid 2px $mid-blue;
border-radius: 2px;
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
color: $mid-blue;
font-size: 9px; // the width of the arrow indicator
@include for-tablet-portrait-up {
right: 20px;
margin-top: -22.5px;
width: 45px;
height: 45px;
line-height: 45px;
font-size: 11px;
}
.accordion-scheme-dark & {
border-color: $white;
color: $white;
}
.uod-icons {
transform: rotate(0deg);
transition: transform .3s $default-animation-curve;
transform-origin: 50%;
.active & {
transform: rotate(-180deg);
}
}
}
a {
&,
&:link {
color: $primary-blue;
}
.accordion-scheme-dark & {
color: $white;
}
}
.accordion-scheme-dark & {
color: $white;
}
}
&-content {
position: relative;
transition: max-height .3s $default-animation-curve;
overflow: hidden;
&:focus {
outline: none;
}
&.active {
margin-bottom: $margin-extra-small;
border-bottom: 1px dashed $dark-grey;
}
&-inner {
padding: 10px;
@include for-tablet-portrait-up {
padding: $margin-extra-small;
}
.full-width & {
@include full-bleed-inset;
padding-top: 10px;
padding-bottom: 10px;
@include for-tablet-portrait-up {
padding-top: $margin-extra-small;
padding-bottom: $margin-extra-small;
}
}
}
}
.collapse {
transition: max-height .3s $default-animation-curve;
max-height: 0;
&.active {
max-height: 100vh;
}
}
}
/**
* This a modified version of houdinijs v9.4.2 - https://github.com/cferdinandi/houdini
* Modified to add the ability to toggle panels without updating the page hash, via the useHashClass setting.
*/
(function (root, factory) {
if ( typeof define === 'function' && define.amd ) {
define([], factory(root));
} else if ( typeof exports === 'object' ) {
module.exports = factory(root);
} else {
root.houdini = factory(root);
}
})(typeof global !== 'undefined' ? global : this.window || this.global, function (root) {
'use strict';
//
// Variables
//
var houdini = {}; // Object for public APIs
var supports = 'querySelector' in document && 'addEventListener' in root && 'classList' in document.createElement('_'); // Feature test
var settings, collapse;
// Default settings
var defaults = {
selectorToggle: '[data-collapse]',
selectorContent: '.collapse',
toggleActiveClass: 'active',
contentActiveClass: 'active',
useHashClass: 'usehash',
initClass: 'js-houdini',
stopVideo: true,
callbackOpen: function () {},
callbackClose: function () {}
};
//
// Methods
//
/**
* A simple forEach() implementation for Arrays, Objects and NodeLists
* @private
* @param {Array|Object|NodeList} collection Collection of items to iterate
* @param {Function} callback Callback function for each iteration
* @param {Array|Object|NodeList} scope Object/NodeList/Array that forEach is iterating over (aka `this`)
*/
var forEach = function (collection, callback, scope) {
if (Object.prototype.toString.call(collection) === '[object Object]') {
for (var prop in collection) {
if (Object.prototype.hasOwnProperty.call(collection, prop)) {
callback.call(scope, collection[prop], prop, collection);
}
}
} else {
for (var i = 0, len = collection.length; i < len; i++) {
callback.call(scope, collection[i], i, collection);
}
}
};
/**
* Merge defaults with user options
* @private
* @param {Object} defaults Default settings
* @param {Object} options User options
* @returns {Object} Merged values of defaults and options
*/
var extend = function () {
// Variables
var extended = {};
var deep = false;
var i = 0;
var length = arguments.length;
// Check if a deep merge
if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) {
deep = arguments[0];
i++;
}
// Merge the object into the extended object
var merge = function (obj) {
for ( var prop in obj ) {
if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {
// If deep merge and property is an object, merge properties
if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {
extended[prop] = extend( true, extended[prop], obj[prop] );
} else {
extended[prop] = obj[prop];
}
}
}
};
// Loop through each object and conduct a merge
for ( ; i < length; i++ ) {
var obj = arguments[i];
merge(obj);
}
return extended;
};
/**
* Get the closest matching element up the DOM tree
* @param {Element} elem Starting element
* @param {String} selector Selector to match against (class, ID, or data attribute)
* @return {Boolean|Element} Returns false if not match found
*/
var getClosest = function ( elem, selector ) {
// Element.matches() polyfill
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
// Get closest match
for ( ; elem && elem !== document; elem = elem.parentNode ) {
if ( elem.matches( selector ) ) return elem;
}
return null;
};
/**
* Escape special characters for use with querySelector
* @public
* @param {String} id The anchor ID to escape
* @author Mathias Bynens
* @link https://github.com/mathiasbynens/CSS.escape
*/
var escapeCharacters = function ( id ) {
// Remove leading hash
if ( id.charAt(0) === '#' ) {
id = id.substr(1);
}
var string = String(id);
var length = string.length;
var index = -1;
var codeUnit;
var result = '';
var firstCodeUnit = string.charCodeAt(0);
while (++index < length) {
codeUnit = string.charCodeAt(index);
// Note: there’s no need to special-case astral symbols, surrogate
// pairs, or lone surrogates.
// If the character is NULL (U+0000), then throw an
// `InvalidCharacterError` exception and terminate these steps.
if (codeUnit === 0x0000) {
throw new InvalidCharacterError(
'Invalid character: the input contains U+0000.'
);
}
if (
// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
// U+007F, […]
(codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F ||
// If the character is the first character and is in the range [0-9]
// (U+0030 to U+0039), […]
(index === 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
// If the character is the second character and is in the range [0-9]
// (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
(
index === 1 &&
codeUnit >= 0x0030 && codeUnit <= 0x0039 &&
firstCodeUnit === 0x002D
)
) {
// http://dev.w3.org/csswg/cssom/#escape-a-character-as-code-point
result += '\\' + codeUnit.toString(16) + ' ';
continue;
}
// If the character is not handled by one of the above rules and is
// greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
// is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
// U+005A), or [a-z] (U+0061 to U+007A), […]
if (
codeUnit >= 0x0080 ||
codeUnit === 0x002D ||
codeUnit === 0x005F ||
codeUnit >= 0x0030 && codeUnit <= 0x0039 ||
codeUnit >= 0x0041 && codeUnit <= 0x005A ||
codeUnit >= 0x0061 && codeUnit <= 0x007A
) {
// the character itself
result += string.charAt(index);
continue;
}
// Otherwise, the escaped character.
// http://dev.w3.org/csswg/cssom/#escape-a-character
result += '\\' + string.charAt(index);
}
return '#' + result;
};
/**
* Stop YouTube, Vimeo, and HTML5 videos from playing when leaving the slide
* @private
* @param {Element} content The content container the video is in
* @param {String} activeClass The class asigned to expanded content areas
*/
var stopVideos = function ( content, settings ) {
// Check if stop video enabled
if ( !settings.stopVideo ) return;
// Only run if content container is open
if ( !content.classList.contains( settings.contentActiveClass ) ) return;
// Check if the video is an iframe or HTML5 video
var iframe = content.querySelector( 'iframe');
var video = content.querySelector( 'video' );
// Stop the video
if ( iframe ) {
var iframeSrc = iframe.src;
iframe.src = iframeSrc;
}
if ( video ) {
video.pause();
}
};
/**
* Add focus to content
* @private
* @param {node} content The content to bring into focus
* @param {object} settings Options
*/
var adjustFocus = function ( content, settings ) {
if ( content.hasAttribute( 'data-houdini-no-focus' ) ) return;
// If content is closed, remove tabindex
if ( !content.classList.contains( settings.contentActiveClass ) ) {
if ( content.hasAttribute( 'data-houdini-focused' ) ) {
content.removeAttribute( 'tabindex' );
}
return;
}
// Get current position on the page
var position = {
x: root.pageXOffset,
y: root.pageYOffset
};
// Set focus and reset position to account for page jump on focus
content.focus();
if ( document.activeElement.id !== content.id ) {
content.setAttribute( 'tabindex', '-1' );
content.setAttribute( 'data-houdini-focused', true );
content.focus();
}
root.scrollTo( position.x, position.y );
};
/**
* Open collapsed content
* @public
* @param {String} contentID The ID of the content area to close
* @param {Element} toggle The element that toggled the close action
* @param {Object} options
*/
houdini.closeContent = function ( contentID, toggle, options ) {
// Variables
var localSettings = extend( settings || defaults, options || {} ); // Merge user options with defaults
var content = document.querySelector( escapeCharacters( contentID ) ); // Get content area
// Sanity check
if ( !content ) return;
// Toggle the content
stopVideos( content, localSettings ); // If content area is closed, stop playing any videos
if ( toggle ) {
toggle.classList.remove( localSettings.toggleActiveClass );// Change text on collapse toggle
}
content.classList.remove( localSettings.contentActiveClass ); // Collapse or expand content area
adjustFocus( content, localSettings );
// Run callbacks after toggling content
localSettings.callbackClose( content, toggle );
};
/**
* Open collapsed content
* @public
* @param {String} contentID The ID of the content area to open
* @param {Element} toggle The element that toggled the open action
* @param {Object} options
*/
houdini.openContent = function ( contentID, toggle, options ) {
// Variables
var localSettings = extend( settings || defaults, options || {} ); // Merge user options with defaults
var content = document.querySelector( escapeCharacters( contentID ) ); // Get content area
var group = toggle && toggle.hasAttribute( 'data-group') ? document.querySelectorAll('[data-group="' + toggle.getAttribute( 'data-group') + '"]') : [];
// Sanity check
if ( !content ) return;
// If a group, close all other content areas
forEach(group, function (item) {
houdini.closeContent( item.hash, item );
});
// Open the content
if ( toggle ) {
toggle.classList.add( localSettings.toggleActiveClass ); // Change text on collapse toggle
}
content.classList.add( localSettings.contentActiveClass ); // Collapse or expand content area
adjustFocus( content, localSettings );
content.removeAttribute( 'data-houdini-no-focus' );
// Run callbacks after toggling content
localSettings.callbackOpen( content, toggle );
};
/**
* Handle has change event
* @private
*/
var hashChangeHandler = function (event) {
// Get hash from URL
var hash = root.location.hash;
// If clicked collapse is cached, reset it's ID
if ( collapse ) {
collapse.id = collapse.getAttribute( 'data-collapse-id' );
collapse = null;
}
// If there's a URL hash, open the content with matching ID
if ( !hash ) return;
var toggle = document.querySelector( settings.selectorToggle + '[href*="' + hash + '"]' );
houdini.openContent( hash, toggle );
};
/**
* Handle toggle click events
* @private
*/
var clickHandler = function (event) {
// Don't run if right-click or command/control + click
if ( event.button !== 0 || event.metaKey || event.ctrlKey ) return;
// Check if a toggle was clicked
var toggle = getClosest( event.target, settings.selectorToggle );
if ( !toggle || !toggle.hash ) return;
// Custom: Check if we're toggling without updating hashes
if ( !toggle.classList.contains( settings.useHashClass ) ) {
event.preventDefault();
if ( !toggle.classList.contains( settings.toggleActiveClass ) ) {
houdini.openContent( toggle.hash, toggle );
return;
}
}
// If the tab is already open, close it
if ( toggle.classList.contains( settings.toggleActiveClass ) ) {
event.preventDefault();
houdini.closeContent( toggle.hash, toggle );
return;
}
// Get the collapse content
collapse = document.querySelector( toggle.hash );
// If tab content exists, save the ID as a data attribute and remove it (prevents scroll jump)
if ( !collapse ) return;
collapse.setAttribute( 'data-collapse-id', collapse.id );
collapse.id = '';
// If no hash change event will happen, fire manually
if ( toggle.hash === root.location.hash ) {
event.preventDefault();
hashChangeHandler();
}
};
/**
* Handle content focus events
* @private
*/
var focusHandler = function (event) {
// Variables
collapse = getClosest( event.target, settings.selectorContent );
// Only run if content exists and isn't open already
if ( !collapse || collapse.classList.contains( settings.contentActiveClass ) ) return;
// Save the ID as a data attribute and remove it (prevents scroll jump)
var hash = collapse.id;
collapse.setAttribute( 'data-collapse-id', hash );
collapse.setAttribute( 'data-houdini-no-focus', true );
collapse.id = '';
// If no hash change event will happen, fire manually
if ( hash === root.location.hash.substring(1) ) {
hashChangeHandler();
return;
}
// Otherwise, update the hash
root.location.hash = hash;
};
/**
* Destroy the current initialization.
* @public
*/
houdini.destroy = function () {
if ( !settings ) return;
document.documentElement.classList.remove( settings.initClass );
document.removeEventListener('click', clickHandler, false);
document.removeEventListener('focus', focusHandler, true);
root.removeEventListener('hashchange', hashChangeHandler, false);
settings = null;
collapse = null;
};
/**
* Initialize Houdini
* @public
* @param {Object} options User settings
*/
houdini.init = function ( options ) {
// feature test
if ( !supports ) return;
// Destroy any existing initializations
houdini.destroy();
// Merge user options with defaults
settings = extend( defaults, options || {} );
// Add class to HTML element to activate conditional CSS
document.documentElement.classList.add( settings.initClass );
// Listen for all click events
document.addEventListener('click', clickHandler, false);
document.addEventListener('focus', focusHandler, true);
root.addEventListener('hashchange', hashChangeHandler, false);
// If URL has a hash, activate hashed content by default
hashChangeHandler();
};
//
// Public APIs
//
return houdini;
});