Skip to content

Instantly share code, notes, and snippets.

@connrs
Created September 26, 2010 23:18
Show Gist options
  • Save connrs/598406 to your computer and use it in GitHub Desktop.
Save connrs/598406 to your computer and use it in GitHub Desktop.
/**
* @author connrs
* @version 1
*/
Object.prototype.objectType = function(){return (s_ob_type = this.toString().match(/object\s+(\w+)/)[1])?s_ob_type:'undefined'}
var MediaQuerySupport = function(d,w){
var head = d.getElementsByTagName('head')[0],
body = d.getElementsByTagName('body')[0],
date = new Date().getTime(),
style_sheets = d.styleSheets;
function arrayInString(sNeedle,aHaystack) {
var matching_index = -1;
for(var i=0;i<aHaystack.length;i++){if(sNeedle.indexOf(aHaystack[i]) != -1) {matching_index = i;}}
return matching_index;
}
function getStyleSheetSources() {
var style_elements = document.getElementsByTagName('style'),
link_elements = document.getElementsByTagName('link');
for(var i=0;i<link_elements.length;i++) {
var rel_attr = link_elements[i].getAttribute('rel')
if(/stylesheet/.test(rel_attr)) style_elements.push(rel_attr);
}
return style_elements
}
function setStyle(element,css_text) {element.style.cssText = css_text;}
function getStyle(element,property) {
if (element.currentStyle)
var value = element.currentStyle[property];
else if (window.getComputedStyle)
var value = document.defaultView.getComputedStyle(element,null).getPropertyValue(property);
return value;
}
function parseMedia(link){
var media = link.getAttribute('media'),
pMin = /\(\s*min-width\s*:\s*(\d+)px\s*\)/,
pMax = /\(\s*max-width\s*:\s*(\d+)px\s*\)/,
resMin,
resMax,
supportedMedia = ['handheld', 'all', 'screen', 'projection', 'tty', 'tv', 'print'],
curMedia,
mediaString = [];
media = (!media) ? ['all'] : media.split(',');
for(var i=0;i<media.length;i++) {
curMedia = arrayInString(media[i],supportedMedia);
if(curMedia != -1) {
curMedia = supportedMedia[curMedia];
if(!resMin) {
resMin = pMin.exec(media[i]);
if(resMin) resMin = parseInt(resMin[1], 10);
}
if(!resMax) {
resMax = pMax.exec(media[i]);
if(resMax) resMax = parseInt(resMax[1], 10);
}
mediaString.push(curMedia);
}
}
if(resMin || resMax) {
styles.push({
obj: link,
min: resMin,
max: resMax,
medium: mediaString.join(','),
used: false
});
}
}
function extractInlineMediaQueries() {
for(var i=0;i<style_sheets.length;i++) {
var rules = style_sheets[i].cssRules?style_sheets[i].cssRules:style_sheets[i].rules;
for(var j=0;j<rules.length;j++) {
var rule = rules[j];
rule_type = rules[j].objectType();
if(rule_type == 'CSSMediaRule') {
var media_text = rule.media.mediaText,
media_css_rules = rule.cssRules?rule.cssRules:rule.rules,
media_css_text = media_css_rules.join("\n"),
new_style = d.createElement('style');
new_style.setAttribute('media',media_text);
new_style.cssText = media_css_text;
head.appendChild(new_style);
}
}
}
}
return {
testMedia:function(str) {
var div = d.createElement('div'),
style = d.createElement('style');
div.setAttribute('class','testMediaQuery'+date);
setStyle(div,'visibility:hidden;position:absolute');
style.setAttribute('type', 'text/css');
style.setAttribute('media', str);
body.appendChild(div);
head.insertBefore(style,head.firstChild);
var style_sheet = d.styleSheets[d.styleSheets.length],
style_sheet_rules = style_sheet.cssRules?style_sheet.cssRules:style_sheet.rules?style_sheet.rules:false;
if(style_sheet_rules) {
if(style_sheet.insertRule) {
style_sheet.insertRule('.testMediaQuery' + date + ' {display:none !important;}', style_sheet.cssRules.length);
} else if(style_sheet.addRule) {
style_sheet.addRule('.testMediaQuery' + date, 'display:none');
}
}
var test_media_succeeded = getStyle(div,'display') ==='none';
d.removeChild(div);
d.removeChild(style);
return test_media_succeeded;
},
enableMediaQuery:function(){
var styles = [], styleLinks
return {
init: function(){
if (!styleLinks) {
extractInlineMediaQueries();
var stylesheet_sources = getStyleSheetSources(),
resizeTimer;
for(var i=0;i<stylesheet_sources.length;i++) {
parseMedia(stylesheet_sources[i]);
}
//styleLinks = $('link[rel*=style]').each(function(){
// parseMedia(this);
//});
enableMediaQuery.adjust();
$(window).bind('resize.mediaQueries', function(){
clearTimeout(resizeTimer);
resizeTimer = setTimeout( $.enableMediaQuery.adjust , 29);
});
}
},
adjust: function(){
var width = Math.max(document.documentElement.clientWidth,document.body.scrollWidth,document.documentElement.scrollWidth,document.body.offsetWidth,document.documentElement.offsetWidth),addStyles = [], changeQuery, shouldUse, i, len;
for (var i=0,len=styles.length;i<len;i++) {
shouldUse = !styles[i].obj.disabled && ((!(styles[i].min && styles[i].min > width) && !(styles[i].max && styles[i].max < width)) || (!styles[i].max && !styles[i].min));
if(shouldUse) {
var n = styles[i].obj.cloneNode(true);
n.setAttribute('media', styles[i].medium);
n.className = 'insertStyleforMedia' + date;
addStyles.push(n);
if(!styles[i].used){
styles[i].used = true;
changeQuery = true;
}
} else if(styles[i].used!==shouldUse) {
styles[i].used = false;
changeQuery = true;
}
}
if(changeQuery){
$('link.insertStyleforMedia' + date).remove();
for(i=0,len=addStyles.length;i<len;i++){
head.appendChild(addStyles[i]);
}
//repaint
$('body').css('zoom', '1').css('zoom', '');
}
}
};
}
};
}(document,this,undefined);
//convert this to an onload function
(function($){
//make some odd assumption before dom-ready
$.support.mediaQueries = !( $.browser.msie && parseFloat($.browser.version, 10) < 9) || ($.browser.mozilla && parseFloat($.browser.version, 10) < 1.9 );
setTimeout(function(){
if (!$.isReady && document.body && !$.support.mediaQueries) {
try {
$.enableMediaQuery.init();
} catch (e) {}
}
}, 1);
$(function(){
//test media query compatibility
$.support.mediaQueries = $.testMedia('only all');
if (!$.support.mediaQueries) {
$.enableMediaQuery.init();
}
});
})(jQuery);
(function(){
var init_loaded = false,
naughty_sniff_hack_activated = false,
naughty_sniff_hack;
function init(){
if(init_loaded) return;
init_loaded = true;
naughty_sniff_hack = !( $.browser.msie && parseFloat($.browser.version, 10) < 9) || ($.browser.mozilla && parseFloat($.browser.version, 10) < 1.9 );
}
if (document.readyState === "complete") init();
if(document.addEventListener) {
document.addEventListener('DOMContentLoaded',init,false);
window.addEventListener('load',init,false);
} else if(document.attachEvent) {
document.attachEvent('onreadystatechange', init);
window.attachEvent('load',init)
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment