1// JavaScript Document 2 3/** 4 * Interchange module. 5 * @module foundation.interchange 6 * @requires foundation.util.mediaQuery 7 * @requires foundation.util.timerAndImageLoader 8 */ 9!function(Foundation, $) { 10 'use strict'; 11 12 /** 13 * Creates a new instance of Interchange. 14 * @class 15 * @fires Interchange#init 16 * @param {Object} element - jQuery object to add the trigger to. 17 * @param {Object} options - Overrides to the default plugin settings. 18 */ 19 function Interchange(element, options) { 20 this.$element = element; 21 this.options = $.extend({}, Interchange.defaults, options); 22 this.rules = []; 23 this.currentPath = ''; 24 25 this._init(); 26 this._events(); 27 28 Foundation.registerPlugin(this, 'Interchange'); 29 } 30 31 /** 32 * Default settings for plugin 33 */ 34 Interchange.defaults = { 35 /** 36 * Rules to be applied to Interchange elements. Set with the `data-interchange` array notation. 37 * @option 38 */ 39 rules: null 40 }; 41 42 Interchange.SPECIAL_QUERIES = { 43 'landscape': 'screen and (orientation: landscape)', 44 'portrait': 'screen and (orientation: portrait)', 45 '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)' 46 }; 47 48 /** 49 * Initializes the Interchange plugin and calls functions to get interchange functioning on load. 50 * @function 51 * @private 52 */ 53 Interchange.prototype._init = function() { 54 this._addBreakpoints(); 55 this._generateRules(); 56 this._reflow(); 57 }; 58 59 /** 60 * Initializes events for Interchange. 61 * @function 62 * @private 63 */ 64 Interchange.prototype._events = function() { 65 $(window).on('resize.zf.interchange', Foundation.util.throttle(this._reflow.bind(this), 50)); 66 }; 67 68 /** 69 * Calls necessary functions to update Interchange upon DOM change 70 * @function 71 * @private 72 */ 73 Interchange.prototype._reflow = function() { 74 var match; 75 76 // Iterate through each rule, but only save the last match 77 for (var i in this.rules) { 78 var rule = this.rules[i]; 79 80 if (window.matchMedia(rule.query).matches) { 81 match = rule; 82 } 83 } 84 85 if (match) { 86 this.replace(match.path); 87 } 88 }; 89 90 /** 91 * Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object. 92 * @function 93 * @private 94 */ 95 Interchange.prototype._addBreakpoints = function() { 96 for (var i in Foundation.MediaQuery.queries) { 97 var query = Foundation.MediaQuery.queries[i]; 98 Interchange.SPECIAL_QUERIES[query.name] = query.value; 99 } 100 }; 101 102 /** 103 * Checks the Interchange element for the provided media query + content pairings 104 * @function 105 * @private 106 * @param {Object} element - jQuery object that is an Interchange instance 107 * @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys 108 */ 109 Interchange.prototype._generateRules = function() { 110 var rulesList = []; 111 var rules; 112 113 if (this.options.rules) { 114 rules = this.options.rules;
115 } 116 else { 117 rules = this.$element.data('interchange').match(/\[.*?\]/g); 118 } 119 120 for (var i in rules) { 121 var rule = rules[i].slice(1, -1).split(', '); 122 var path = rule.slice(0, -1).join(''); 123 var query = rule[rule.length - 1]; 124 125 if (Interchange.SPECIAL_QUERIES[query]) { 126 query = Interchange.SPECIAL_QUERIES[query]; 127 } 128 129 rulesList.push({ 130 path: path, 131 query: query 132 }); 133 } 134 135 this.rules = rulesList; 136 }; 137 138 /** 139 * Update the `src` property of an image, or change the HTML of a container, to the specified path. 140 * @function 141 * @param {String} path - Path to the image or HTML partial. 142 * @fires Interchange#replaced 143 */ 144 Interchange.prototype.replace = function(path) { 145 if (this.currentPath === path) return; 146 147 var _this = this, 148 trigger = 'replaced.zf.interchange'; 149 150 // Replacing images 151 if (this.$element[0].nodeName === 'IMG') { 152 this.$element.attr('src', path).load(function() { 153 _this.currentPath = path; 154 }) 155 .trigger(trigger); 156 } 157 // Replacing background images 158 else if (path.match(/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i)) { 159 this.$element.css({ 'background-image': 'url('+path+')' }) 160 .trigger(trigger); 161 } 162 // Replacing HTML 163 else { 164 $.get(path, function(response) { 165 _this.$element.html(response) 166 .trigger(trigger); 167 $(response).foundation(); 168 _this.currentPath = path; 169 }); 170 } 171 172 /** 173 * Fires when content in an Interchange element is done being loaded. 174 * @event Interchange#replaced 175 */ 176 // this.$element.trigger('replaced.zf.interchange'); 177 }; 178 /** 179 * Destroys an instance of interchange. 180 * @function 181 */ 182 Interchange.prototype.destroy = function(){ 183 //TODO this. 184 }; 185 Foundation.plugin(Interchange, 'Interchange'); 186 187 // Exports for AMD/Browserify 188 if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') 189 module.exports = Interchange; 190 if (typeof define === 'function') 191 define(['foundation'], function() { 192 return Interchange; 193 }); 194 195}(Foundation, jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.