/**
* @param {!Tag} tag The original tag
* @param {!Object} hosts Map of [host => siteId]
* @param {!Object} sites Map of [siteId => siteConfig]
* @param {string} cacheDir
*/
function (tag, hosts, sites, cacheDir)
{
/**
* Filter a MEDIA tag
*
* This will always invalidate the original tag, and possibly replace it with the tag that
* corresponds to the media site
*
* @param {!Tag} tag The original tag
* @param {!Object} hosts Map of [host => siteId]
* @param {!Object} sites Map of [siteId => siteConfig]
*/
function filterTag(tag, hosts, sites)
{
// Always invalidate this tag
tag.invalidate();
if (tag.hasAttribute('url'))
{
var url = tag.getAttribute('url'),
siteId = getSiteIdFromUrl(url, hosts);
if (sites[siteId])
{
var attributes = getAttributes(url, sites[siteId]);
if (!empty(attributes))
{
createTag(siteId.toUpperCase(), tag).setAttributes(attributes);
}
}
}
}
/**
* Add named captures from a set of regular expressions to a set of attributes
*
* @param {!Object} attributes Associative array of strings
* @param {string} string Text to match
* @param {!Array} regexps List of [regexp, map] pairs
* @return {boolean} Whether any regexp matched
*/
function addNamedCaptures(attributes, string, regexps)
{
var matched = false;
regexps.forEach(function(pair)
{
var regexp = pair[0],
map = pair[1],
m = regexp.exec(string);
if (!m)
{
return;
}
matched = true;
map.forEach(function(name, i)
{
if (m[i] > '' && name > '')
{
attributes[name] = m[i];
}
});
});
return matched;
}
/**
* Create a tag for a media embed
*
* @param {string} tagName Tag's name
* @param {!Tag} tag Reference tag
* @return {!Tag} New tag
*/
function createTag(tagName, tag)
{
var startPos = tag.getPos(),
endTag = tag.getEndTag(),
startLen,
endPos,
endLen;
if (endTag)
{
startLen = tag.getLen();
endPos = endTag.getPos();
endLen = endTag.getLen();
}
else
{
startLen = 0;
endPos = tag.getPos() + tag.getLen();
endLen = 0;
}
return addTagPair(tagName, startPos, startLen, endPos, endLen, tag.getSortPriority());
}
/**
* @param {!Object} attributes
* @return {boolean}
*/
function empty(attributes)
{
for (var attrName in attributes)
{
return false;
}
return true;
}
/**
* Return a set of attributes for given URL based on a site's config
*
* @param {string} url Original URL
* @param {!Object} config Site config
* @return {!Object} Attributes
*/
function getAttributes(url, config)
{
var attributes = {};
addNamedCaptures(attributes, url, config[0]);
return attributes;
}
/**
* Return the siteId that corresponds to given URL
*
* @param {string} url Original URL
* @param {!Object} hosts Map of [hostname => siteId]
* @return {string} URL's siteId, or an empty string
*/
function getSiteIdFromUrl(url, hosts)
{
var m = /^https?:\/\/([^\/]+)/.exec(url.toLowerCase()),
host = m[1] || '';
while (host > '')
{
if (hosts[host])
{
return hosts[host];
}
host = host.replace(/^[^.]*./, '');
}
return '';
}
filterTag(tag, hosts, sites);
}