123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- '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};
|