1;(function ($, window, document, undefined) { 2 'use strict'; 3 4 Foundation.libs.interchange = { 5 name : 'interchange', 6 7 version : '5.5.2', 8 9 cache : {}, 10 11 images_loaded : false, 12 nodes_loaded : false, 13 14 settings : { 15 load_attr : 'interchange', 16 17 named_queries : { 18 'default' : 'only screen', 19 'small' : Foundation.media_queries['small'], 20 'small-only' : Foundation.media_queries['small-only'], 21 'medium' : Foundation.media_queries['medium'], 22 'medium-only' : Foundation.media_queries['medium-only'], 23 'large' : Foundation.media_queries['large'], 24 'large-only' : Foundation.media_queries['large-only'], 25 'xlarge' : Foundation.media_queries['xlarge'], 26 'xlarge-only' : Foundation.media_queries['xlarge-only'], 27 'xxlarge' : Foundation.media_queries['xxlarge'], 28 'landscape' : 'only screen and (orientation: landscape)', 29 'portrait' : 'only screen and (orientation: portrait)', 30 'retina' : 'only screen and (-webkit-min-device-pixel-ratio: 2),' + 31 'only screen and (min--moz-device-pixel-ratio: 2),' + 32 'only screen and (-o-min-device-pixel-ratio: 2/1),' + 33 'only screen and (min-device-pixel-ratio: 2),' + 34 'only screen and (min-resolution: 192dpi),' + 35 'only screen and (min-resolution: 2dppx)' 36 }, 37 38 directives : { 39 replace : function (el, path, trigger) { 40 // The trigger argument, if called within the directive, fires 41 // an event named after the directive on the element, passing 42 // any parameters along to the event that you pass to trigger. 43 // 44 // ex. trigger(), trigger([a, b, c]), or trigger(a, b, c) 45 // 46 // This allows you to bind a callback like so: 47 // $('#interchangeContainer').on('replace', function (e, a, b, c) { 48 // console.log($(this).html(), a, b, c); 49 // }); 50 51 if (el !== null && /IMG/.test(el[0].nodeName)) { 52 var orig_path = el[0].src; 53 54 if (new RegExp(path, 'i').test(orig_path)) { 55 return; 56 } 57 58 el.attr("src", path); 59 60 return trigger(el[0].src); 61 } 62 var last_path = el.data(this.data_attr + '-last-path'), 63 self = this; 64 65 if (last_path == path) { 66 return; 67 } 68 69 if (/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(path)) { 70 $(el).css('background-image', 'url(' + path + ')'); 71 el.data('interchange-last-path', path); 72 return trigger(path); 73 } 74 75 return $.get(path, function (response) { 76 el.html(response); 77 el.data(self.data_attr + '-last-path', path); 78 trigger(); 79 }); 80 81 } 82 } 83 }, 84 85 init : function (scope, method, options) { 86 Foundation.inherit(this, 'throttle random_str'); 87 88 this.data_attr = this.set_data_attr(); 89 $.extend(true, this.settings, method, options); 90 this.bindings(method, options); 91 this.reflow(); 92 }, 93 94 get_media_hash : function () { 95 var mediaHash = ''; 96 for (var queryName in this.settings.named_queries ) { 97 mediaHash += matchMedia(this.settings.named_queries[queryName]).matches.toString(); 98 } 99 return mediaHash; 100 }, 101 102 events : function () { 103 var self = this, prevMediaHash; 104 105 $(window) 106 .off('.interchange') 107 .on('resize.fndtn.interchange', self.throttle(function () { 108 var currMediaHash = self.get_media_hash(); 109 if (currMediaHash !== prevMediaHash) { 110 self.resize(); 111 } 112 prevMediaHash = currMediaHash; 113 }, 50)); 114 115 return this; 116 }, 117 118 resize : function () { 119 var cache = this.cache; 120 121 if (!this.images_loaded || !this.nodes_loaded) { 122 setTimeout($.proxy(this.resize, this), 50); 123 return; 124 } 125 126 for (var uuid in cache) { 127 if (cache.hasOwnProperty(uuid)) { 128 var passed = this.results(uuid, cache[uuid]); 129 if (passed) { 130 this.settings.directives[passed 131 .scenario[1]].call(this, passed.el, passed.scenario[0], (function (passed) { 132 if (arguments[0] instanceof Array) { 133 var args = arguments[0]; 134 } else { 135 var args = Array.prototype.slice.call(arguments, 0); 136 } 137 138 return function() { 139 passed.el.trigger(passed.scenario[1], args); 140 } 141 }(passed))); 142 } 143 } 144 } 145 146 }, 147 148 results : function (uuid, scenarios) { 149 var count = scenarios.length; 150 151 if (count > 0) { 152 var el = this.S('[' + this.add_namespace('data-uuid') + '="' + uuid + '"]'); 153 154 while (count--) { 155 var mq, rule = scenarios[count][2]; 156 if (this.settings.named_queries.hasOwnProperty(rule)) { 157 mq = matchMedia(this.settings.named_queries[rule]); 158 } else { 159 mq = matchMedia(rule); 160 } 161 if (mq.matches) { 162 return {el : el, scenario : scenarios[count]}; 163 } 164 } 165 } 166 167 return false;
168 }, 169 170 load : function (type, force_update) { 171 if (typeof this['cached_' + type] === 'undefined' || force_update) { 172 this['update_' + type](); 173 } 174 175 return this['cached_' + type]; 176 }, 177 178 update_images : function () { 179 var images = this.S('img[' + this.data_attr + ']'), 180 count = images.length, 181 i = count, 182 loaded_count = 0, 183 data_attr = this.data_attr; 184 185 this.cache = {}; 186 this.cached_images = []; 187 this.images_loaded = (count === 0); 188 189 while (i--) { 190 loaded_count++; 191 if (images[i]) { 192 var str = images[i].getAttribute(data_attr) || ''; 193 194 if (str.length > 0) { 195 this.cached_images.push(images[i]); 196 } 197 } 198 199 if (loaded_count === count) { 200 this.images_loaded = true; 201 this.enhance('images'); 202 } 203 } 204 205 return this; 206 }, 207 208 update_nodes : function () { 209 var nodes = this.S('[' + this.data_attr + ']').not('img'), 210 count = nodes.length, 211 i = count, 212 loaded_count = 0, 213 data_attr = this.data_attr; 214 215 this.cached_nodes = []; 216 this.nodes_loaded = (count === 0); 217 218 while (i--) { 219 loaded_count++; 220 var str = nodes[i].getAttribute(data_attr) || ''; 221 222 if (str.length > 0) { 223 this.cached_nodes.push(nodes[i]); 224 } 225 226 if (loaded_count === count) { 227 this.nodes_loaded = true; 228 this.enhance('nodes'); 229 } 230 } 231 232 return this; 233 }, 234 235 enhance : function (type) { 236 var i = this['cached_' + type].length; 237 238 while (i--) { 239 this.object($(this['cached_' + type][i])); 240 } 241 242 return $(window).trigger('resize.fndtn.interchange'); 243 }, 244 245 convert_directive : function (directive) { 246 247 var trimmed = this.trim(directive); 248 249 if (trimmed.length > 0) { 250 return trimmed; 251 } 252 253 return 'replace'; 254 }, 255 256 parse_scenario : function (scenario) { 257 // This logic had to be made more complex since some users were using commas in the url path 258 // So we cannot simply just split on a comma 259 260 var directive_match = scenario[0].match(/(.+),\s*(\w+)\s*$/), 261 // getting the mq has gotten a bit complicated since we started accounting for several use cases 262 // of URLs. For now we'll continue to match these scenarios, but we may consider having these scenarios 263 // as nested objects or arrays in F6. 264 // regex: match everything before close parenthesis for mq 265 media_query = scenario[1].match(/(.*)\)/); 266 267 if (directive_match) { 268 var path = directive_match[1], 269 directive = directive_match[2]; 270 271 } else { 272 var cached_split = scenario[0].split(/,\s*$/), 273 path = cached_split[0], 274 directive = ''; 275 } 276 277 return [this.trim(path), this.convert_directive(directive), this.trim(media_query[1])]; 278 }, 279 280 object : function (el) { 281 var raw_arr = this.parse_data_attr(el), 282 scenarios = [], 283 i = raw_arr.length; 284 285 if (i > 0) { 286 while (i--) { 287 // split array between comma delimited content and mq 288 // regex: comma, optional space, open parenthesis 289 var scenario = raw_arr[i].split(/,\s?\(/); 290 291 if (scenario.length > 1) { 292 var params = this.parse_scenario(scenario); 293 scenarios.push(params); 294 } 295 } 296 } 297 298 return this.store(el, scenarios); 299 }, 300 301 store : function (el, scenarios) { 302 var uuid = this.random_str(), 303 current_uuid = el.data(this.add_namespace('uuid', true)); 304 305 if (this.cache[current_uuid]) { 306 return this.cache[current_uuid]; 307 } 308 309 el.attr(this.add_namespace('data-uuid'), uuid); 310 return this.cache[uuid] = scenarios; 311 }, 312 313 trim : function (str) { 314 315 if (typeof str === 'string') { 316 return $.trim(str); 317 } 318 319 return str; 320 }, 321 322 set_data_attr : function (init) { 323 if (init) { 324 if (this.namespace.length > 0) { 325 return this.namespace + '-' + this.settings.load_attr; 326 } 327 328 return this.settings.load_attr; 329 } 330 331 if (this.namespace.length > 0) { 332 return 'data-' + this.namespace + '-' + this.settings.load_attr; 333 } 334 335 return 'data-' + this.settings.load_attr; 336 }, 337 338 parse_data_attr : function (el) { 339 var raw = el.attr(this.attr_name()).split(/\[(.*?)\]/), 340 i = raw.length, 341 output = []; 342 343 while (i--) { 344 if (raw[i].replace(/[\W\d]+/, '').length > 4) { 345 output.push(raw[i]); 346 } 347 } 348 349 return output; 350 }, 351 352 reflow : function () { 353 this.load('images', true); 354 this.load('nodes', true); 355 } 356 357 }; 358 359}(jQuery, window, window.document));
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.