Skip to content

Instantly share code, notes, and snippets.

@johan
Forked from donut/getBGImgURLsFromCSSs.js
Created October 18, 2012 22:07
Show Gist options
  • Save johan/3915063 to your computer and use it in GitHub Desktop.
Save johan/3915063 to your computer and use it in GitHub Desktop.
Produces an array of background-image urls used in the page
/* Builds a list of background image urls from inline styles / linked stylesheets
*
* @return {array}
* Array of unique absolute image URLs from inline styles/readable style sheets
*/
function getBackgroundImages(doc) {
doc = doc || document;
var sheets = doc.styleSheets
, url_re = /\burl[(\s]+['"]?([^"')]+)["']?[\s)]+/g
, _slice = Array.prototype.slice
, bgImg = style('backgroundImage')
, getUrls = allMatches.bind(url_re)
, uniq = {}
, urls = []
, sheet, rules, rule, selector, bg, match, rel_url
;
function array(ish) { return _slice.call(ish, 0); }
function style(c) { return function(r) { return r&&r.style&&r.style[c]; }; }
function resolve(url, base_url) {
var old_base = document.querySelector('base')
, old_href = old_base && old_base.href
, doc_head = doc.head || doc.getElementsByTagName('head')[0]
, new_base = old_base || doc_head.appendChild(doc.createElement('base'))
, resolver = doc.createElement('a')
, real_url
;
new_base.href = base_url;
resolver.href = url;
real_url = resolver.href;
if (old_base) old_base.href = old_href;
else doc_head.removeChild(new_base);
return real_url;
}
// add all inline background-image style attributes
array(doc.querySelectorAll('[style]')).forEach(addBGUrls);
// add all background-image rules used on page from stylesheets
for (var s = 0; sheet = sheets[s]; s++) {
try { rules = sheet.rules ? sheet.rules : sheet.cssRules; }
catch (e) { continue; } // avoids cross-domain exceptions
if (!rules) continue;
for (var r = 0; rule = rules[r]; r++) {
if (!(bg = bgImg(rule)) || // not a background?
!(selector = rule.selectorText) || // not a selector rule?
!doc.querySelector(selector)) // not used in this page?
continue;
url_re.lastIndex = 0; // start scanning from start of rule
while ((match = url_re.exec(bg))) {
rel_url = match[1];
uniq[resolve(rel_url, sheet.href)] = 1;
}
}
}
for (url in uniq) urls.push(url);
return urls;
}
// sloppier version that doesn't uniquify, resolve or filter for used urls:
function getAllBackgroundImages(doc) {
var _slice = Array.prototype.slice
, bgImg = style('backgroundImage')
, urls = []
, url_re = /\burl[(\s]+['"]?([^"')]+)["']?[\s)]+/g
, getUrls = allMatches.bind(url_re)
;
function array(ish) { return _slice.call(ish, 0); }
function style(c) { return function(r) { return r&&r.style&&r.style[c]; }; }
function allMatches(s) {
var res = [], got;
this.lastIndex = 0;
while ((got = this.exec(s)))
res.push(got[1]);
return res;
}
function addBGUrls(of) {
urls.push.apply(urls, getUrls(bgImg(of) || ''));
}
doc = doc || document;
// add all inline background-image style attributes
array(doc.querySelectorAll('[style]')).forEach(addBGUrls);
// add all background-image urls found in stylesheets
array(doc.styleSheets).forEach(function(ss) {
array(ss.rules || ss.cssRules || []).forEach(addBGUrls);
});
return urls;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment