Last active
August 29, 2015 14:04
-
-
Save gavinballard/e8272673f9e155464151 to your computer and use it in GitHub Desktop.
Potential selectivizr.js + respond.js combination for Shopify.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! Respond.js: min/max-width media query polyfill. Remote proxy (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ | |
(function(win, doc, undefined) { | |
// Add a modified version of selectivizr.js here. Could remove the methods | |
// that fetch remote stylesheets (as Respond.js would be doing that for us | |
// via the proxy method), but expose the code that parses and applies | |
// patches as a public method - something like Selectivizr.parseStyleSheets(). | |
var docElem = doc.documentElement, | |
proxyURL = doc.getElementById("respond-proxy").href, | |
redirectURL = (doc.getElementById("respond-redirect") || location).href, | |
baseElem = doc.getElementsByTagName("base")[0], | |
urls = [], | |
refNode; | |
function encode(url){ | |
return win.encodeURIComponent(url); | |
} | |
function fakejax( url, callback ){ | |
var iframe, | |
AXO; | |
// All hail Google http://j.mp/iKMI19 | |
// Behold, an iframe proxy without annoying clicky noises. | |
if ( "ActiveXObject" in win ) { | |
AXO = new ActiveXObject( "htmlfile" ); | |
AXO.open(); | |
AXO.write( '<iframe id="x"></iframe>' ); | |
AXO.close(); | |
iframe = AXO.getElementById( "x" ); | |
} else { | |
iframe = doc.createElement( "iframe" ); | |
iframe.style.cssText = "position:absolute;top:-99em"; | |
docElem.insertBefore(iframe, docElem.firstElementChild || docElem.firstChild ); | |
} | |
iframe.src = checkBaseURL(proxyURL) + "?url=" + encode(redirectURL) + "&css=" + encode(checkBaseURL(url)); | |
function checkFrameName() { | |
var cssText; | |
try { | |
cssText = iframe.contentWindow.name; | |
} | |
catch (e) { } | |
if (cssText) { | |
// We've got what we need. Stop the iframe from loading further content. | |
iframe.src = "about:blank"; | |
iframe.parentNode.removeChild(iframe); | |
iframe = null; | |
// Per http://j.mp/kn9EPh, not taking any chances. Flushing the ActiveXObject | |
if (AXO) { | |
AXO = null; | |
if (win.CollectGarbage) { | |
win.CollectGarbage(); | |
} | |
} | |
callback(cssText); | |
} | |
else{ | |
win.setTimeout(checkFrameName, 100); | |
} | |
} | |
win.setTimeout(checkFrameName, 500); | |
} | |
function checkBaseURL(href) { | |
if (baseElem && href.indexOf(baseElem.href) === -1) { | |
bref = (/\/$/).test(baseElem.href) ? baseElem.href : (baseElem.href + "/"); | |
href = bref + href; | |
} | |
return href; | |
} | |
function checkRedirectURL() { | |
// IE6 & IE7 don't build out absolute urls in <link /> attributes. | |
// So respond.proxy.gif remains relative instead of http://example.com/respond.proxy.gif. | |
// This trickery resolves that issue. | |
if (~ !redirectURL.indexOf(location.host)) { | |
var fakeLink = doc.createElement("div"); | |
fakeLink.innerHTML = '<a href="' + redirectURL + '"></a>'; | |
docElem.insertBefore(fakeLink, docElem.firstElementChild || docElem.firstChild ); | |
// Grab the parsed URL from that dummy object | |
redirectURL = fakeLink.firstChild.href; | |
// Clean up | |
fakeLink.parentNode.removeChild(fakeLink); | |
fakeLink = null; | |
} | |
} | |
function buildUrls(){ | |
var links = doc.getElementsByTagName( "link" ); | |
for( var i = 0, linkl = links.length; i < linkl; i++ ){ | |
var thislink = links[i], | |
href = links[i].href, | |
extreg = (/^([a-zA-Z:]*\/\/(www\.)?)/).test( href ), | |
ext = (baseElem && !extreg) || extreg; | |
//make sure it's an external stylesheet | |
if( thislink.rel.indexOf( "stylesheet" ) >= 0 && ext ){ | |
(function( link ){ | |
fakejax( href, function( css ){ | |
// Instead of the line below, you'd have: | |
// link.styleSheet.rawCssText = Selectivizr.parseStyleSheet(css); | |
// | |
// Would have to investigate how Selectivizr handles media queries | |
// to make sure there aren't any conflicts but I don't think that | |
// would be an issue. | |
link.styleSheet.rawCssText = css; | |
respond.update(); | |
} ); | |
})( thislink ); | |
} | |
} | |
} | |
if( !respond.mediaQueriesSupported ){ | |
checkRedirectURL(); | |
buildUrls(); | |
} | |
})( window, document ); |
That looks good to me. I don't see anything specific in selectivizr that deals with media queries so that shouldn't be an issue.
Let me know if there is anything I can do to help out or test. As mentioned in my tweet, some of the JS going on in respond and selectivizr are over my head but your flow seems to have things covered.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey @cshold, not sure how much time you have to look at this (selectivizr.js + respond.js on Shopify), but
this would be what I'm thinking - basically;
respond.liquid
if using my Respond.js workaround - see comments added at lines #L4-L7;parseStylesheets()
method from Selectivizr to the Respond.js code;buildUrls()
method of Respond.js when setting therawCssText
property onlink.styleSheet
(see comments at #L118-123).I think that would work - Respond.js does the fetching through the proxy as normal, then Selectivizr patches it before Respond.js interprets it.
Thoughts welcome!