biofriction-wp-theme/node_modules/foundation-sites/js/foundation.interchange.js

211 lines
5.3 KiB
JavaScript

'use strict';
import $ from 'jquery';
import { MediaQuery } from './foundation.util.mediaQuery';
import { Plugin } from './foundation.core.plugin';
import { GetYoDigits } from './foundation.core.utils';
/**
* Interchange module.
* @module foundation.interchange
* @requires foundation.util.mediaQuery
*/
class Interchange extends Plugin {
/**
* Creates a new instance of Interchange.
* @class
* @name Interchange
* @fires Interchange#init
* @param {Object} element - jQuery object to add the trigger to.
* @param {Object} options - Overrides to the default plugin settings.
*/
_setup(element, options) {
this.$element = element;
this.options = $.extend({}, Interchange.defaults, options);
this.rules = [];
this.currentPath = '';
this.className = 'Interchange'; // ie9 back compat
this._init();
this._events();
}
/**
* Initializes the Interchange plugin and calls functions to get interchange functioning on load.
* @function
* @private
*/
_init() {
MediaQuery._init();
var id = this.$element[0].id || GetYoDigits(6, 'interchange');
this.$element.attr({
'data-resize': id,
'id': id
});
this._addBreakpoints();
this._generateRules();
this._reflow();
}
/**
* Initializes events for Interchange.
* @function
* @private
*/
_events() {
this.$element.off('resizeme.zf.trigger').on('resizeme.zf.trigger', () => this._reflow());
}
/**
* Calls necessary functions to update Interchange upon DOM change
* @function
* @private
*/
_reflow() {
var match;
// Iterate through each rule, but only save the last match
for (var i in this.rules) {
if(this.rules.hasOwnProperty(i)) {
var rule = this.rules[i];
if (window.matchMedia(rule.query).matches) {
match = rule;
}
}
}
if (match) {
this.replace(match.path);
}
}
/**
* Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object.
* @function
* @private
*/
_addBreakpoints() {
for (var i in MediaQuery.queries) {
if (MediaQuery.queries.hasOwnProperty(i)) {
var query = MediaQuery.queries[i];
Interchange.SPECIAL_QUERIES[query.name] = query.value;
}
}
}
/**
* Checks the Interchange element for the provided media query + content pairings
* @function
* @private
* @param {Object} element - jQuery object that is an Interchange instance
* @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys
*/
_generateRules(element) {
var rulesList = [];
var rules;
if (this.options.rules) {
rules = this.options.rules;
}
else {
rules = this.$element.data('interchange');
}
rules = typeof rules === 'string' ? rules.match(/\[.*?, .*?\]/g) : rules;
for (var i in rules) {
if(rules.hasOwnProperty(i)) {
var rule = rules[i].slice(1, -1).split(', ');
var path = rule.slice(0, -1).join('');
var query = rule[rule.length - 1];
if (Interchange.SPECIAL_QUERIES[query]) {
query = Interchange.SPECIAL_QUERIES[query];
}
rulesList.push({
path: path,
query: query
});
}
}
this.rules = rulesList;
}
/**
* Update the `src` property of an image, or change the HTML of a container, to the specified path.
* @function
* @param {String} path - Path to the image or HTML partial.
* @fires Interchange#replaced
*/
replace(path) {
if (this.currentPath === path) return;
var _this = this,
trigger = 'replaced.zf.interchange';
// Replacing images
if (this.$element[0].nodeName === 'IMG') {
this.$element.attr('src', path).on('load', function() {
_this.currentPath = path;
})
.trigger(trigger);
}
// Replacing background images
else if (path.match(/\.(gif|jpg|jpeg|png|svg|tiff)([?#].*)?/i)) {
path = path.replace(/\(/g, '%28').replace(/\)/g, '%29');
this.$element.css({ 'background-image': 'url('+path+')' })
.trigger(trigger);
}
// Replacing HTML
else {
$.get(path, function(response) {
_this.$element.html(response)
.trigger(trigger);
$(response).foundation();
_this.currentPath = path;
});
}
/**
* Fires when content in an Interchange element is done being loaded.
* @event Interchange#replaced
*/
// this.$element.trigger('replaced.zf.interchange');
}
/**
* Destroys an instance of interchange.
* @function
*/
_destroy() {
this.$element.off('resizeme.zf.trigger')
}
}
/**
* Default settings for plugin
*/
Interchange.defaults = {
/**
* Rules to be applied to Interchange elements. Set with the `data-interchange` array notation.
* @option
* @type {?array}
* @default null
*/
rules: null
};
Interchange.SPECIAL_QUERIES = {
'landscape': 'screen and (orientation: landscape)',
'portrait': 'screen and (orientation: portrait)',
'retina': 'only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)'
};
export {Interchange};