├── .gitattributes ├── README.md ├── rwd.retrofit.min.js ├── .gitignore └── rwd.retrofit.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RWD Retrofit 2 | ============ 3 | 4 | ### Allows an existing "desktop site" to co-exist with a "responsive site", while also able to serve the desktop site to a different breakpoint on "mobile" 5 | 6 | It's also able to serve the desktop site to a different breakpoint on mobile touch devices - useful for serving the desktop site to tablets, for example 7 | 8 | Returns an object containing the desktop (`rwdRetrofit.desktop`) and optional mobile (`rwdRetrofit.mobile`) media queries as strings for responding to media queries with JS; for example, by using enquire.js (http://wickynilliams.github.com/enquire.js) 9 | 10 | --- 11 | 12 | **Usage:** 13 | 14 | 1. Set up the viewport with: `` 15 | 16 | 2. Reference the existing desktop stylesheet in a `` with a relevant media query, eg. `media="all and (min-width: 990px)"` and `class="rwdretrofit-desktop"` 17 | 18 | 3. Reference the new responsive stylesheet in a `` with a relevant media query, eg. `media="all and (max-width: 989px)"` and `class="rwdretrofit-mobile"` 19 | 20 | 4. Add an optional `data-breakpoint-width="xxx"` attribute to the desktop stylesheet ``, where xxx is the pixel-width that the desktop breakpoint will occur on mobile devices - eg. 768 for iPads and other large tablets 21 | 22 | 5. Add an optional `data-viewport-width="xxx"` attribute to the desktop stylesheet ``, where xxx is the pixel width that the desktop viewport will be set to on mobile devices 23 | 24 | 6. Add an optional data-debug="true" attribute to the desktop stylesheet `` to force non-touch devices to use the `data-breakpoint-width` override 25 | 26 | --- 27 | 28 | You can see it in action on: http://rwdretrofit.izilla.com.au and http://www.rubik.com.au -------------------------------------------------------------------------------- /rwd.retrofit.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RWD Retrofit v1.7 3 | * Allows an existing "desktop site" to co-exist with a "responsive site", while also able to serve the desktop site to a different breakpoint on "mobile" - useful for serving the desktop site to tablets, for example 4 | * 5 | * Returns an object containing the desktop (rwdRetrofit.desktop) and optional mobile (rwdRetrofit.mobile) media queries as strings for responding to media queries with JS; for example, by using enquire.js (http://wickynilliams.github.com/enquire.js) 6 | * 7 | * Copyright (c) 2013 Izilla Partners Pty Ltd 8 | * 9 | * http://www.izilla.com.au 10 | * 11 | * Licensed under the MIT license 12 | */ 13 | ;var rwdRetrofit=(function(){if(!document.querySelector||!document.getElementsByClassName||typeof(document.documentElement.clientWidth)=="undefined"){return}var l=document.querySelector('meta[name="viewport"]'),u=document.getElementsByClassName("rwdretrofit-desktop"),b=document.getElementsByClassName("rwdretrofit-mobile");if(!l||u.length===0||b.length===0){return}var g="ontouchstart" in window,o="content",f="media",e=l&&l.getAttribute(o),h="width=980",a=250,c="onorientationchange" in window,n=c?"orientationchange":"resize",s=u[0].getAttribute(f),w=b[0].getAttribute(f),m=u[0].getAttribute("data-breakpoint-width"),t,p=u[0].getAttribute("data-viewport-width"),d=u[0].getAttribute("data-debug"),v={};if(g||d==="true"){if(m){t=m}else{t=s.replace(/.*?min-width:\s?(\d*).*/g,"$1")}if(p&&parseInt(p)>=parseInt(t)){h=h.replace(/\d+/,p)}else{if(t>980){h=h.replace(/\d+/,t)}}}else{t=s.replace(/.*?min-width:\s?(\d*).*/g,"$1")}s=s.replace(/(min-width:\s?)\d*/g,"$1"+t);w=w.replace(/(max-width:\s?)\d*/g,"$1"+(t-1));v.desktop=s,v.mobile=w;if(g||d==="true"){for(var r=0;r=t){l.setAttribute(o,h)}},a)}k();window.addEventListener(n,k,false)}return v})(); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /rwd.retrofit.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RWD Retrofit v1.7 3 | * Allows an existing "desktop site" to co-exist with a "responsive site", while also able to serve the desktop site to a different breakpoint on "mobile" - useful for serving the desktop site to tablets, for example 4 | * 5 | * Returns an object containing the desktop (rwdRetrofit.desktop) and optional mobile (rwdRetrofit.mobile) media queries as strings for responding to media queries with JS; for example, by using enquire.js (http://wickynilliams.github.com/enquire.js) 6 | * 7 | * 8 | * Usage: 9 | * 1. Set up the viewport with: 10 | * 2. Reference the existing desktop stylesheet with a with a relevant media query, eg. media="all and (min-width: 990px)" and class="rwdretrofit-desktop" 11 | * 3. Reference the new responsive stylesheet with a with a relevant media query, eg. media="all and (max-width: 989px)" and class="rwdretrofit-mobile" 12 | * 4. Add an optional data-breakpoint-width="xxx" attribute to the desktop stylesheet , where xxx is the pixel width that the desktop breakpoint will occur on mobile devices - eg. 768 for iPads and other large tablets 13 | * 5. Add an optional data-viewport-width="xxx" attribute to the desktop stylesheet , where xxx is the pixel width that the desktop viewport will be set to on mobile devices 14 | * 6. Add an optional data-debug="true" attribute to the desktop stylesheet to force non-touch devices to use the data-breakpoint-width override 15 | * 16 | * Copyright (c) 2013 Izilla Partners Pty Ltd 17 | * 18 | * http://www.izilla.com.au 19 | * 20 | * Licensed under the MIT license 21 | */ 22 | ;var rwdRetrofit = (function() { 23 | if (!document.querySelector || !document.getElementsByClassName || typeof(document.documentElement.clientWidth) == 'undefined') 24 | return; 25 | 26 | var meta = document.querySelector('meta[name="viewport"]'), 27 | desktop = document.getElementsByClassName('rwdretrofit-desktop'), 28 | mobile = document.getElementsByClassName('rwdretrofit-mobile'); 29 | 30 | if (!meta || desktop.length === 0 || mobile.length === 0) 31 | return; 32 | 33 | var supportsTouch = 'ontouchstart' in window, 34 | content = 'content', 35 | media = 'media', 36 | initialContent = meta && meta.getAttribute(content), 37 | desktopContent = 'width=980', 38 | duration = 250, 39 | supportsOrientationChange = 'onorientationchange' in window, 40 | orientationEvent = supportsOrientationChange ? 'orientationchange' : 'resize', 41 | desktopMQ = desktop[0].getAttribute(media), 42 | mobileMQ = mobile[0].getAttribute(media), 43 | dataBreakpointWidth = desktop[0].getAttribute('data-breakpoint-width'), 44 | breakpointWidth, 45 | dataViewportWidth = desktop[0].getAttribute('data-viewport-width'), 46 | dataDebug = desktop[0].getAttribute('data-debug'), 47 | mediaQueries = {}; 48 | 49 | if (supportsTouch || dataDebug === 'true') { 50 | if (dataBreakpointWidth) 51 | breakpointWidth = dataBreakpointWidth; 52 | else 53 | breakpointWidth = desktopMQ.replace(/.*?min-width:\s?(\d*).*/g, '$1'); 54 | 55 | if (dataViewportWidth && parseInt(dataViewportWidth) >= parseInt(breakpointWidth)) { 56 | desktopContent = desktopContent.replace(/\d+/, dataViewportWidth); 57 | } 58 | else { 59 | if (breakpointWidth > 980) 60 | desktopContent = desktopContent.replace(/\d+/, breakpointWidth); 61 | } 62 | } 63 | else { 64 | breakpointWidth = desktopMQ.replace(/.*?min-width:\s?(\d*).*/g, '$1'); 65 | } 66 | 67 | desktopMQ = desktopMQ.replace(/(min-width:\s?)\d*/g, '$1' + breakpointWidth); 68 | mobileMQ = mobileMQ.replace(/(max-width:\s?)\d*/g, '$1' + (breakpointWidth-1)); 69 | 70 | mediaQueries.desktop = desktopMQ, 71 | mediaQueries.mobile = mobileMQ; 72 | 73 | if (supportsTouch || dataDebug === 'true') { 74 | for (var i=0; i < desktop.length; i++) { 75 | desktop[i].setAttribute(media, desktopMQ); 76 | } 77 | 78 | for (var j=0; j < mobile.length; j++) { 79 | mobile[j].setAttribute(media, mobileMQ); 80 | } 81 | } 82 | 83 | if (supportsTouch) { 84 | function switchViewport() { 85 | meta.setAttribute(content, initialContent); 86 | window.setTimeout(function() { 87 | if (document.documentElement.clientWidth >= breakpointWidth) 88 | meta.setAttribute(content, desktopContent); 89 | }, duration); 90 | } 91 | 92 | switchViewport(); 93 | window.addEventListener(orientationEvent, switchViewport, false); 94 | } 95 | 96 | return mediaQueries; 97 | })(); --------------------------------------------------------------------------------