You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
9.0 KiB
344 lines
9.0 KiB
;(function ($, window, document, undefined) { |
|
'use strict'; |
|
|
|
Foundation.libs.interchange = { |
|
name : 'interchange', |
|
|
|
version : '5.3.3', |
|
|
|
cache : {}, |
|
|
|
images_loaded : false, |
|
nodes_loaded : false, |
|
|
|
settings : { |
|
load_attr : 'interchange', |
|
|
|
named_queries : { |
|
'default' : 'only screen', |
|
small : Foundation.media_queries.small, |
|
medium : Foundation.media_queries.medium, |
|
large : Foundation.media_queries.large, |
|
xlarge : Foundation.media_queries.xlarge, |
|
xxlarge: Foundation.media_queries.xxlarge, |
|
landscape : 'only screen and (orientation: landscape)', |
|
portrait : 'only 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)' |
|
}, |
|
|
|
directives : { |
|
replace: function (el, path, trigger) { |
|
// The trigger argument, if called within the directive, fires |
|
// an event named after the directive on the element, passing |
|
// any parameters along to the event that you pass to trigger. |
|
// |
|
// ex. trigger(), trigger([a, b, c]), or trigger(a, b, c) |
|
// |
|
// This allows you to bind a callback like so: |
|
// $('#interchangeContainer').on('replace', function (e, a, b, c) { |
|
// console.log($(this).html(), a, b, c); |
|
// }); |
|
|
|
if (/IMG/.test(el[0].nodeName)) { |
|
var orig_path = el[0].src; |
|
|
|
if (new RegExp(path, 'i').test(orig_path)) return; |
|
|
|
el[0].src = path; |
|
|
|
return trigger(el[0].src); |
|
} |
|
var last_path = el.data(this.data_attr + '-last-path'), |
|
self = this; |
|
|
|
if (last_path == path) return; |
|
|
|
if (/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(path)) { |
|
$(el).css('background-image', 'url('+path+')'); |
|
el.data('interchange-last-path', path); |
|
return trigger(path); |
|
} |
|
|
|
return $.get(path, function (response) { |
|
el.html(response); |
|
el.data(self.data_attr + '-last-path', path); |
|
trigger(); |
|
}); |
|
|
|
} |
|
} |
|
}, |
|
|
|
init : function (scope, method, options) { |
|
Foundation.inherit(this, 'throttle random_str'); |
|
|
|
this.data_attr = this.set_data_attr(); |
|
$.extend(true, this.settings, method, options); |
|
this.bindings(method, options); |
|
this.load('images'); |
|
this.load('nodes'); |
|
}, |
|
|
|
get_media_hash : function() { |
|
var mediaHash=''; |
|
for (var queryName in this.settings.named_queries ) { |
|
mediaHash += matchMedia(this.settings.named_queries[queryName]).matches.toString(); |
|
} |
|
return mediaHash; |
|
}, |
|
|
|
events : function () { |
|
var self = this, prevMediaHash; |
|
|
|
$(window) |
|
.off('.interchange') |
|
.on('resize.fndtn.interchange', self.throttle(function () { |
|
var currMediaHash = self.get_media_hash(); |
|
if (currMediaHash !== prevMediaHash) { |
|
self.resize(); |
|
} |
|
prevMediaHash = currMediaHash; |
|
}, 50)); |
|
|
|
return this; |
|
}, |
|
|
|
resize : function () { |
|
var cache = this.cache; |
|
|
|
if(!this.images_loaded || !this.nodes_loaded) { |
|
setTimeout($.proxy(this.resize, this), 50); |
|
return; |
|
} |
|
|
|
for (var uuid in cache) { |
|
if (cache.hasOwnProperty(uuid)) { |
|
var passed = this.results(uuid, cache[uuid]); |
|
|
|
if (passed) { |
|
this.settings.directives[passed |
|
.scenario[1]].call(this, passed.el, passed.scenario[0], function () { |
|
if (arguments[0] instanceof Array) { |
|
var args = arguments[0]; |
|
} else { |
|
var args = Array.prototype.slice.call(arguments, 0); |
|
} |
|
|
|
passed.el.trigger(passed.scenario[1], args); |
|
}); |
|
} |
|
} |
|
} |
|
|
|
}, |
|
|
|
results : function (uuid, scenarios) { |
|
var count = scenarios.length; |
|
|
|
if (count > 0) { |
|
var el = this.S('[' + this.add_namespace('data-uuid') + '="' + uuid + '"]'); |
|
|
|
while (count--) { |
|
var mq, rule = scenarios[count][2]; |
|
if (this.settings.named_queries.hasOwnProperty(rule)) { |
|
mq = matchMedia(this.settings.named_queries[rule]); |
|
} else { |
|
mq = matchMedia(rule); |
|
} |
|
if (mq.matches) { |
|
return {el: el, scenario: scenarios[count]}; |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
}, |
|
|
|
load : function (type, force_update) { |
|
if (typeof this['cached_' + type] === 'undefined' || force_update) { |
|
this['update_' + type](); |
|
} |
|
|
|
return this['cached_' + type]; |
|
}, |
|
|
|
update_images : function () { |
|
var images = this.S('img[' + this.data_attr + ']'), |
|
count = images.length, |
|
i = count, |
|
loaded_count = 0, |
|
data_attr = this.data_attr; |
|
|
|
this.cache = {}; |
|
this.cached_images = []; |
|
this.images_loaded = (count === 0); |
|
|
|
while (i--) { |
|
loaded_count++; |
|
if (images[i]) { |
|
var str = images[i].getAttribute(data_attr) || ''; |
|
|
|
if (str.length > 0) { |
|
this.cached_images.push(images[i]); |
|
} |
|
} |
|
|
|
if (loaded_count === count) { |
|
this.images_loaded = true; |
|
this.enhance('images'); |
|
} |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
update_nodes : function () { |
|
var nodes = this.S('[' + this.data_attr + ']').not('img'), |
|
count = nodes.length, |
|
i = count, |
|
loaded_count = 0, |
|
data_attr = this.data_attr; |
|
|
|
this.cached_nodes = []; |
|
this.nodes_loaded = (count === 0); |
|
|
|
|
|
while (i--) { |
|
loaded_count++; |
|
var str = nodes[i].getAttribute(data_attr) || ''; |
|
|
|
if (str.length > 0) { |
|
this.cached_nodes.push(nodes[i]); |
|
} |
|
|
|
if(loaded_count === count) { |
|
this.nodes_loaded = true; |
|
this.enhance('nodes'); |
|
} |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
enhance : function (type) { |
|
var i = this['cached_' + type].length; |
|
|
|
while (i--) { |
|
this.object($(this['cached_' + type][i])); |
|
} |
|
|
|
return $(window).trigger('resize').trigger('resize.fndtn.interchange'); |
|
}, |
|
|
|
convert_directive : function (directive) { |
|
|
|
var trimmed = this.trim(directive); |
|
|
|
if (trimmed.length > 0) { |
|
return trimmed; |
|
} |
|
|
|
return 'replace'; |
|
}, |
|
|
|
parse_scenario : function (scenario) { |
|
// This logic had to be made more complex since some users were using commas in the url path |
|
// So we cannot simply just split on a comma |
|
var directive_match = scenario[0].match(/(.+),\s*(\w+)\s*$/), |
|
media_query = scenario[1]; |
|
|
|
if (directive_match) { |
|
var path = directive_match[1], |
|
directive = directive_match[2]; |
|
} |
|
else { |
|
var cached_split = scenario[0].split(/,\s*$/), |
|
path = cached_split[0], |
|
directive = ''; |
|
} |
|
|
|
return [this.trim(path), this.convert_directive(directive), this.trim(media_query)]; |
|
}, |
|
|
|
object : function(el) { |
|
var raw_arr = this.parse_data_attr(el), |
|
scenarios = [], |
|
i = raw_arr.length; |
|
|
|
if (i > 0) { |
|
while (i--) { |
|
var split = raw_arr[i].split(/\((.*?)(\))$/); |
|
|
|
if (split.length > 1) { |
|
var params = this.parse_scenario(split); |
|
scenarios.push(params); |
|
} |
|
} |
|
} |
|
|
|
return this.store(el, scenarios); |
|
}, |
|
|
|
store : function (el, scenarios) { |
|
var uuid = this.random_str(), |
|
current_uuid = el.data(this.add_namespace('uuid', true)); |
|
|
|
if (this.cache[current_uuid]) return this.cache[current_uuid]; |
|
|
|
el.attr(this.add_namespace('data-uuid'), uuid); |
|
|
|
return this.cache[uuid] = scenarios; |
|
}, |
|
|
|
trim : function(str) { |
|
|
|
if (typeof str === 'string') { |
|
return $.trim(str); |
|
} |
|
|
|
return str; |
|
}, |
|
|
|
set_data_attr: function (init) { |
|
if (init) { |
|
if (this.namespace.length > 0) { |
|
return this.namespace + '-' + this.settings.load_attr; |
|
} |
|
|
|
return this.settings.load_attr; |
|
} |
|
|
|
if (this.namespace.length > 0) { |
|
return 'data-' + this.namespace + '-' + this.settings.load_attr; |
|
} |
|
|
|
return 'data-' + this.settings.load_attr; |
|
}, |
|
|
|
parse_data_attr : function (el) { |
|
var raw = el.attr(this.attr_name()).split(/\[(.*?)\]/), |
|
i = raw.length, |
|
output = []; |
|
|
|
while (i--) { |
|
if (raw[i].replace(/[\W\d]+/, '').length > 4) { |
|
output.push(raw[i]); |
|
} |
|
} |
|
|
|
return output; |
|
}, |
|
|
|
reflow : function () { |
|
this.load('images', true); |
|
this.load('nodes', true); |
|
} |
|
|
|
}; |
|
|
|
}(jQuery, window, window.document));
|
|
|