├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── demo └── index.html ├── dist └── jquery.projectblocker.min.js ├── gruntfile.js ├── html └── jquery.projectblocker.html ├── less └── jquery.projectblocker.less ├── package.json └── src └── jquery.projectblocker.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.sublime-project 3 | *.sublime-workspace 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mike Zarandona 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ProjectBlocker 2 | 3 | [![Bower version](https://badge.fury.io/bo/project-blocker.png)](http://badge.fury.io/bo/project-blocker) 4 | [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/) 5 | 6 | A handy jQuery solution for blocking responsive, IE, or incomplete bits from being seen while in development. 7 | 8 | [GitHub](https://github.com/mike-zarandona/ProjectBlocker) | [Demo](http://codepen.io/mike-zarandona/full/bNYvmw/) 9 | 10 | _Features_: 11 | - **Block responsive web design** - gives you the ability to demo coded previews without worrying about how the project might look on mobile devices. 12 | - **Block the homepage** - show a polite message that a page isn't yet ready to be viewed to keep visitors out of broken or unfinished areas of preview sites. 13 | - **Block Internet Explorer** - _duh_. 14 | - **Customizable and friendly blocking messages** - because good UX is the right thing to do. 15 | - **Bypass for developers** - for sanity. 16 | 17 | ![ProjectBlocker in Action](http://i.imgur.com/Vliy8dR.gif) 18 | 19 |
20 | 21 | 22 | 23 | ## Getting Started 24 | 1. Include jQuery. 25 | 1. Include `dist/jquery.projectblocker.min.js`. 26 | 1. When the `document` is `ready()`, initialize **`ProjectBlocker`**: 27 | 28 | ```javascript 29 | $(document).on('ready', function() { 30 | $.projectBlocker(); 31 | }); 32 | ``` 33 | 34 | ### Full Example 35 | ```javascript 36 | $(document).on('ready', function() { 37 | $.projectBlocker({ 38 | responsive: 'hide', 39 | minWidth: 1200, 40 | 41 | homepage: 'hide', 42 | homepageSelector: '#wrapper.homepage', 43 | 44 | ie: 'hide' 45 | }); 46 | }); 47 | ``` 48 | 49 | When all else fails, check out the `demo/`. 50 | 51 |
52 | 53 | 54 | 55 | ## A Note on Functionality 56 | **`ProjectBlocker`** blocks responsive web design by throwing up the friendly blocking message plus overlay, but _also_ adds a CSS `max-width` property to the `` so that things don't look broken underneath. We just thought you might like to know. 57 | 58 |
59 | 60 | 61 | 62 | ## Developer Workaround 63 | Once **`ProjectBlocker`** has been initialized using the Getting Started steps, it will be immediately active for all visitors. This is awesome, but becomes a huge pain once development resumes. To fix that, we have some handy URL flags: 64 | 65 | ### `?dev=true` 66 | Append this to the end of your URL to _bypass_ **`ProjectBlocker`** and enable `Developer Mode`. You'll get a handy console notification letting you know that **`ProjectBlocker`** is still running (after the first refresh), but is letting you through since you're cool. 67 | 68 | Additionally the script will write a `localStorage` key value pair matched to the URL on which you're browsing. This means that you only have to use `?dev=true` once and it will continuously let you through without bugging you each time, even if you don't use this URL flag in future. How nice. 69 | 70 | ### `?dev=off` 71 | Append this to the end of your URL to turn off `Developer Mode` to see the **`ProjectBlocker`** warnings as usual. 72 | 73 |
74 | 75 | 76 | 77 | ## Options 78 | | Option | Type | Default | Description | 79 | |-------- |------ |--------- |------------- | 80 | | **`responsive`** | _string_ | `'hide'` | Hides or shows responsive web design to the visitor. Used along with `minWidth`. | 81 | | **`minWidth`** | _int_ | `'0'` | The minimum viewing width of the page before the warning is introduced. | 82 | | **`homepage`** | _string_ | `'show'` | Hides or shows the homepage of the site. Used along with `homepageSelector`. | 83 | | **`homepageSelector`** | _string_ | `null` | Any time this jQuery selector is matched the page will be hidden. Handy for the homepage or anything you're trying to block. | 84 | | **`ie`** | _string_ | `'hide'` | Hides or shows Internet Explorer. | 85 | 86 |
87 | 88 | 89 | 90 | ## Customization with Grunt 91 | [Grunt](http://gruntjs.com) was used to develop and build **`ProjectBlocker`** - this makes it very easy to grab a fork and modify the HTML and styles (written in LESS) to your bidding. 92 | 93 | [GruntJS.com Getting Started: Working with an Existing Grunt Project](http://gruntjs.com/getting-started#working-with-an-existing-grunt-project) 94 | 95 | **ProTip: _Don't forget to head into `html/jquery.projectblocker.html` and change the "Author" name!_** 96 | 97 | ### The Sources 98 | The DOM structure of the overlay as well as the styles are **not** included in the main source script file (`src/jquery.projectblocker.js`). They exist in their respective folders (`html/`, `less/`) and are made available in the minified version of the script through global variables. 99 | 100 | #### HTML 101 | HTML is built from `html/jquery.projectblocker.html`, and is made available in the global variable `pbOverlayDOM`. 102 | 103 | #### Styles 104 | Styles are built from `less/jquery.projectblocker.less`, and are made available in the global variable `pbStyles`. 105 | 106 | ### Building the Project 107 | To build a fresh custom copy of **`ProjectBlocker`** first get started with Grunt by running `npm install`, then run `grunt build`. This will recompile the HTML (from `html/`) and LESS (from `less/`) into JavaScript global variables and append them into a freshly minified version at `dist/jquery.projectblocker.min.js`. 108 | 109 | One _gotcha_ is that changes to the DOM of **`ProjectBlocker`** will likely require changes to the responsive design. _Womp womp._ 110 | 111 | It is encouraged that developers inspect the demo as well as the HTML and LESS before customizing by running `grunt server`. 112 | 113 |
114 | 115 | 116 | 117 | ## Super Good Advice 118 | **Remember to remove `ProjectBlocker` before going live!** Or for peace of mind write a conditional to only load it on development and staging URLs. 119 | 120 |
121 | 122 | 123 | 124 | ## Changelog 125 | 126 | ### 1.0.0 127 | - Initial public release. 128 | 129 |
130 | 131 | 132 | ## Author 133 | Mike Zarandona | [http://twitter.com/mikezarandona](http://twitter.com/mikezarandona) 134 | 135 |
136 | 137 | 138 | ## License 139 | **`ProjectBlocker`** is available under the MIT license. -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project-blocker", 3 | "version": "1.0.0", 4 | "homepage": "https://github.com/mike-zarandona/ProjectBlocker", 5 | "authors": [ 6 | "Mike Zarandona " 7 | ], 8 | "description": "A handy jQuery solution for blocking responsive, IE, or incomplete bits from being seen while in development.", 9 | "main": "build/jquery.projectblocker.min.js", 10 | "keywords": [ 11 | "responsive", 12 | "block", 13 | "project", 14 | "projectblocker", 15 | "development", 16 | "staging" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "tests" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ProjectBlocker Demo 14 | 15 | 16 | 17 | 63 | 64 | 65 | 68 | 69 | 70 |
71 |
72 |

ProjectBlocker Demo

73 |

A handy jQuery solution for blocking responsive, IE, or incomplete bits from being seen while in development.

74 |

75 | GitHub | 76 | Demo 77 |

78 | 79 |
80 | 81 |

Make this window less than 800px in width to see the magic happen.

82 | 83 |

Pop a /?dev=true on the end of the URL to bypass, and check the console message (after a reload). Turn off Developer Mode with /?dev=off.

84 | 85 |

Also try viewing in Internet Explorer!

86 | 87 | 88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | 97 | 98 |
99 |
100 | 101 | 102 | 103 | 104 | 105 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /dist/jquery.projectblocker.min.js: -------------------------------------------------------------------------------- 1 | /*! ProjectBlocker - v1.0.0 - http://github.com/mike-zarandona/ProjectBlocker */ 2 | !function(a){var b={responsive:"hide",minWidth:0,homepage:"show",homepageSelector:null,ie:"hide"};a.projectBlocker=function(c){function d(b){m.append(pbOverlayDOM);var d=a(".pb-responsive-overlay"),e=a(".pb-message-wrapper"),f=a(".pb-pixel-counter");"ie"==b?(m.css("min-width",c.minWidth+"px"),f.html(a(".pb-message-wrapper .signed")),d.addClass("block no-arrows"),e.addClass("ie"),i=!0):"homepage"==b?(m.css("min-width",c.minWidth+"px"),f.html(a(".pb-message-wrapper .signed")),d.addClass("block no-arrows"),e.addClass("homepage"),i=!0):"rwd"==b&&(e.addClass("rwd"),(window.innerWidth').append('').append('"),h&&0===a("meta[name=viewport]").length&&l.append(''),c.minWidth++,"off"==f("dev")&&e()&&(g(0),localStorage.clear()),e()&&(k=localStorage.getItem("PB-"+document.location.hostname),"true"==k&&g(1)),"true"!=f("dev")&&"true"!=k){if("hide"==c.ie){var n=!!navigator.userAgent.match(/Trident.*rv\:11\./);n&&d("ie")}"hide"!=c.homepage||i||a(c.homepageSelector).length>0&&d("homepage"),"hide"!=c.responsive||i||d("rwd")}else e()&&localStorage.setItem("PB-"+document.location.hostname,"true")}}(jQuery);; 3 | var pbOverlayDOM="

Hello!

This site is currently in development, and right now Internet Explorer is temporarily being hidden as it is not yet finished. Please check back again soon!

In the mean time, please try using a different browser such as Google Chrome or Mozilla Firefox. Thanks!

This site is currently in development, and right now the homepage is temporarily being hidden as it is not yet finished being built. Please check back again soon!

In the mean time, please feel free to access the CMS to start editing your content or to go to a secondary page to view the rest of your site in progress. Thanks!

This site is in development, and the \"responsive\" component (what makes the site resize to fit every screen) is not yet in place.

In the mean time, please expand the width of your browser. As soon as you do, this message will disappear and you can get to viewing the site!

- Author

Pixels Left
to Go

0
";; 4 | var pbStyles=".pb-responsive-overlay{display:block!important;position:fixed;opacity:0;width:100%;height:100%;top:0;left:0;background-color:#000;background-color:rgba(0,0,0,.96);font-family:'Open Sans',sans-serif;z-index:-9999;-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms}.pb-responsive-overlay.show{opacity:1;z-index:999999999}.pb-responsive-overlay.block{display:block!important;opacity:1!important;z-index:999999999!important}.pb-responsive-overlay.block .pb-message-wrapper{padding-left:1.5em;padding-right:1.5em}.pb-responsive-overlay.no-arrows .pb-message-wrapper .pb-pixel-counter:after,.pb-responsive-overlay.no-arrows .pb-message-wrapper .pb-pixel-counter:before{display:none}.pb-responsive-overlay .pb-message-wrapper{-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;padding:5px 2.5em;border-radius:50%;background-color:#fff;color:#111;text-align:center;position:absolute;top:10%;left:50%;margin-left:-250px;height:500px;width:500px;-webkit-box-shadow:0 20px 0 rgba(0,0,0,.33);-moz-box-shadow:0 20px 0 rgba(0,0,0,.33);box-shadow:0 20px 0 rgba(0,0,0,.33)}.pb-responsive-overlay .pb-message-wrapper h1{font:82px/1em 'Open Sans Condensed',sans-serif;margin:.25em auto;color:#999;font-weight:300;-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms}.pb-responsive-overlay .pb-message-wrapper p{text-align:left;font:16px/1.75em 'Open Sans',sans-serif;-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms}.pb-responsive-overlay .pb-message-wrapper p.one{margin-bottom:0;text-align:center;display:none}.pb-responsive-overlay .pb-message-wrapper p.two{float:left;width:48%;text-align:right;margin-bottom:.75em;display:none}.pb-responsive-overlay .pb-message-wrapper p.signed{clear:both;float:left;width:55%;text-align:right;font:300 32px/1em 'Open Sans Condensed',sans-serif;margin:.5em 0}.pb-responsive-overlay .pb-message-wrapper p a{color:#111}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter{position:absolute;height:200px;width:200px;right:5px;bottom:65px;border-radius:50%;background-color:#e15e00;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms;-webkit-box-shadow:0 20px 0 rgba(0,0,0,.33);-moz-box-shadow:0 20px 0 rgba(0,0,0,.33);box-shadow:0 20px 0 rgba(0,0,0,.33);-webkit-animation:pulse 3s infinite;-moz-animation:pulse 3s infinite;-o-animation:pulse 3s infinite;animation:pulse 3s infinite}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:after,.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:before{content:'\\00AB';position:absolute;display:block;font:64px/1em 'Open Sans',sans-serif;color:#fa6900;width:.5em;height:1em;top:50%;right:100%;margin-top:-.5em}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:before{-webkit-animation:widerleft 3s infinite;-moz-animation:widerleft 3s infinite;-o-animation:widerleft 3s infinite;animation:widerleft 3s infinite}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:after{content:'\\00BB';right:auto;left:100%;-webkit-animation:widerright 3s infinite;-moz-animation:widerright 3s infinite;-o-animation:widerright 3s infinite;animation:widerright 3s infinite}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter p{color:#fff;text-align:center;padding-top:.3em;font:20px/1em 'Open Sans',sans-serif;margin-bottom:0;-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter span{color:#fff;font:300 102px/1em 'Open Sans Condensed',sans-serif;-webkit-transition:all 300ms;-moz-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter .signed{font-family:'Open Sans Condensed',sans-serif;font-size:42px;margin-top:1.5em;width:100%}.pb-responsive-overlay .pb-message-wrapper.ie{padding-left:2em;padding-right:2em}.pb-responsive-overlay .pb-message-wrapper.homepage p.one.homepage,.pb-responsive-overlay .pb-message-wrapper.homepage p.two.homepage,.pb-responsive-overlay .pb-message-wrapper.ie p.one.ie,.pb-responsive-overlay .pb-message-wrapper.ie p.two.ie,.pb-responsive-overlay .pb-message-wrapper.rwd p.one.rwd,.pb-responsive-overlay .pb-message-wrapper.rwd p.two.rwd{display:block}@media screen and (max-width:600px){.pb-responsive-overlay .pb-message-wrapper{height:400px;width:400px;margin-left:-200px}.pb-responsive-overlay .pb-message-wrapper h1{font-size:62px}.pb-responsive-overlay .pb-message-wrapper p{font-size:14px;line-height:1.25em}.pb-responsive-overlay .pb-message-wrapper p.signed{font-size:28px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter{height:160px;width:160px;bottom:55px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:after,.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:before{font-size:48px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter p{font-size:16px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter span{font-size:82px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter .signed{margin-top:1.25em;font-size:38px}}@media screen and (max-width:480px){.pb-responsive-overlay .pb-message-wrapper{padding:5px 1em;height:300px;width:300px;margin-left:-150px}.pb-responsive-overlay .pb-message-wrapper h1{font-size:42px;margin-bottom:0}.pb-responsive-overlay .pb-message-wrapper p{font-size:12px;line-height:1.2em}.pb-responsive-overlay .pb-message-wrapper p.signed{font-size:22px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter{height:135px;width:135px;bottom:25px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:after,.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter:before{font-size:32px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter p{font-size:16px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter span{font-size:62px}.pb-responsive-overlay .pb-message-wrapper .pb-pixel-counter .signed{margin-top:1.5em;font-size:30px}}@-webkit-keyframes widerleft{0,100%{right:100%}50%{right:105%}}@-moz-keyframes widerleft{0,100%{right:100%}50%{right:105%}}@-o-keyframes widerleft{0,100%{right:100%}50%{right:105%}}@keyframes widerleft{0,100%{right:100%}50%{right:105%}}@-webkit-keyframes widerright{0,100%{left:100%}50%{left:105%}}@-moz-keyframes widerright{0,100%{left:100%}50%{left:105%}}@-o-keyframes widerright{0,100%{left:100%}50%{left:105%}}@keyframes widerright{0,100%{left:100%}50%{left:105%}}@-webkit-keyframes pulse{0,100%{background-color:#c75400}50%{background-color:#fa6900}}@-moz-keyframes pulse{0,100%{background-color:#c75400}50%{background-color:#fa6900}}@-o-keyframes pulse{0,100%{background-color:#c75400}50%{background-color:#fa6900}}@keyframes pulse{0,100%{background-color:#c75400}50%{background-color:#fa6900}}"; 5 | -------------------------------------------------------------------------------- /gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.registerTask('watch', [ 'watch' ]); 4 | grunt.registerTask('build', [ 'clean:pre', 'mkdir:build', 'html2str:overlay', 'rename:html', 'less', 'cssmin', 'CSStoJS:files', 'uglify:dist', 'concat:js', 'clean:post' ]); 5 | grunt.registerTask('server', [ 'connect:server', 'watch' ]); 6 | 7 | grunt.initConfig({ 8 | pkg: grunt.file.readJSON('package.json'), 9 | mkdir: { 10 | build: { 11 | options: { 12 | mode: 0777, 13 | create: ['build'] 14 | } 15 | } 16 | }, 17 | jshint: { 18 | options: { 19 | globals: { 20 | jQuery: true 21 | } 22 | }, 23 | js: { 24 | src: ['src/*.js'] 25 | } 26 | }, 27 | concat: { 28 | options: { 29 | separator: ';\n' 30 | }, 31 | js: { 32 | src: [ 33 | 'build/jquery.projectblocker.js', 34 | 'build/jquery.projectblocker.html.js', 35 | 'build/jquery.projectblocker.css.js' 36 | ], 37 | dest: 'dist/jquery.projectblocker.min.js' 38 | } 39 | }, 40 | uglify: { 41 | options: { 42 | mangle: { 43 | except: [ 'jQuery', 'pbOverlayDOM', 'pbStyles', 'projectBlocker' ] 44 | }, 45 | compress: { 46 | unused: false 47 | }, 48 | preserveComments: 'some', 49 | banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - http://github.com/mike-zarandona/ProjectBlocker */\n' 50 | }, 51 | dist: { 52 | src: [ 'src/jquery.projectblocker.js' ], 53 | dest: 'build/jquery.projectblocker.js' 54 | } 55 | }, 56 | html2str: { 57 | overlay: { 58 | options: { 59 | prefix: 'var pbOverlayDOM=', 60 | suffix: ';', 61 | src: 'html/jquery.projectblocker.html', 62 | dest: 'build' 63 | } 64 | } 65 | }, 66 | rename: { 67 | html: { 68 | files: { 69 | 'build/jquery.projectblocker.html.js': [ 'build/jquery.projectblocker.js' ] 70 | } 71 | } 72 | }, 73 | less: { 74 | style: { 75 | files: { 76 | "build/jquery.projectblocker-styles.css": "less/jquery.projectblocker.less" 77 | } 78 | } 79 | }, 80 | cssmin: { 81 | target: { 82 | src: 'build/jquery.projectblocker-styles.css', 83 | dest: 'build/jquery.projectblocker-styles.min.css' 84 | } 85 | }, 86 | CSStoJS: { 87 | options: { 88 | varName: 'pbStyles' 89 | }, 90 | files: { 91 | src: 'build/jquery.projectblocker-styles.min.css', 92 | dest: 'build/jquery.projectblocker.css.js' 93 | } 94 | }, 95 | clean: { 96 | pre: [ 'dist/jquery.projectblocker.min.js' ], 97 | post: [ 'build' ] 98 | }, 99 | connect: { 100 | server: { 101 | options: { 102 | port: 9002, 103 | hostname: 'localhost' 104 | } 105 | } 106 | }, 107 | 108 | watch: { 109 | js: { 110 | files: [ 'src/*.js' ], 111 | tasks: [ 'jshint:js', 'clean:pre', 'mkdir:build', 'html2str:overlay', 'rename:html', 'less', 'cssmin', 'CSStoJS:files', 'uglify:dist', 'concat:js', 'clean:post' ], 112 | options: { 113 | livereload: true 114 | } 115 | }, 116 | } 117 | }); 118 | 119 | grunt.loadNpmTasks('grunt-contrib-jshint'); 120 | grunt.loadNpmTasks('grunt-contrib-uglify'); 121 | grunt.loadNpmTasks('grunt-contrib-less'); 122 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 123 | grunt.loadNpmTasks('grunt-contrib-clean'); 124 | grunt.loadNpmTasks('grunt-contrib-watch'); 125 | grunt.loadNpmTasks('grunt-contrib-concat'); 126 | grunt.loadNpmTasks('grunt-contrib-rename'); 127 | grunt.loadNpmTasks('grunt-contrib-connect'); 128 | grunt.loadNpmTasks('grunt-html2str'); 129 | grunt.loadNpmTasks('grunt-csstojs'); 130 | grunt.loadNpmTasks('grunt-mkdir'); 131 | }; 132 | -------------------------------------------------------------------------------- /html/jquery.projectblocker.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /less/jquery.projectblocker.less: -------------------------------------------------------------------------------- 1 | //****************************************************************************/ 2 | // Variables 3 | //****************************************************************************/ 4 | /* Colors */ 5 | @main: rgb(250, 105, 0); 6 | @white: rgb(255, 255, 255); 7 | 8 | /* Fonts */ 9 | @sans: "Open Sans", sans-serif; 10 | @sans-condensed: "Open Sans Condensed", sans-serif; 11 | 12 | 13 | 14 | //****************************************************************************/ 15 | // Main Styles 16 | //****************************************************************************/ 17 | .pb-responsive-overlay { 18 | display: block !important; 19 | position: fixed; 20 | opacity: 0; 21 | width: 100%; 22 | height: 100%; 23 | top: 0; 24 | left: 0; 25 | background-color: rgb(0, 0, 0); 26 | background-color: rgba(0, 0, 0, 0.96); 27 | font-family: @sans; 28 | z-index: -9999; 29 | .transition; 30 | 31 | &.show { 32 | opacity: 1; 33 | z-index: 999999999; 34 | } 35 | 36 | &.block { 37 | display: block !important; 38 | opacity: 1 !important; 39 | z-index: 999999999 !important; 40 | 41 | .pb-message-wrapper { 42 | padding-left: 1.5em; 43 | padding-right: 1.5em; 44 | } 45 | } 46 | 47 | &.no-arrows .pb-message-wrapper .pb-pixel-counter { 48 | &:before, &:after { display: none; } 49 | } 50 | 51 | .pb-message-wrapper { 52 | .transition; 53 | .box-sizing; 54 | padding: 5px 2.5em; 55 | border-radius: 50%; 56 | 57 | background-color: #fff; 58 | color: #111; 59 | text-align: center; 60 | 61 | position: absolute; 62 | 63 | top: 10%; 64 | left: 50%; 65 | margin-left: -250px; 66 | height: 500px; 67 | width: 500px; 68 | .box-shadow(0 20px 0 rgba(0, 0, 0, 0.33)); 69 | 70 | h1 { 71 | font: 82px/1em @sans-condensed; 72 | margin: 0.25em auto; 73 | color: #999; 74 | font-weight: 300; 75 | .transition; 76 | } 77 | 78 | p { 79 | text-align: left; 80 | font: 16px/1.75em @sans; 81 | .transition; 82 | 83 | &.one { 84 | margin-bottom: 0; 85 | text-align: center; 86 | display: none; 87 | } 88 | 89 | &.two { 90 | float: left; 91 | width: 48%; 92 | text-align: right; 93 | margin-bottom: 0.75em; 94 | display: none; 95 | } 96 | 97 | &.signed { 98 | clear: both; 99 | float: left; 100 | width: 55%; 101 | text-align: right; 102 | font: 300 32px/1em @sans-condensed; 103 | margin: 0.5em 0; 104 | } 105 | 106 | a { color: #111; } 107 | } 108 | 109 | .pb-pixel-counter { 110 | position: absolute; 111 | height: 200px; 112 | width: 200px; 113 | right: 5px; 114 | bottom: 65px; 115 | border-radius: 50%; 116 | background-color: darken(@main, 5%); 117 | .box-sizing; 118 | .transition; 119 | .box-shadow(0 20px 0 rgba(0, 0, 0, 0.33)); 120 | // border: 10px solid @main; 121 | 122 | -webkit-animation: pulse 3s infinite; 123 | -moz-animation: pulse 3s infinite; 124 | -o-animation: pulse 3s infinite; 125 | animation: pulse 3s infinite; 126 | 127 | 128 | &:before, &:after { 129 | content: "\\00AB"; 130 | position: absolute; 131 | display: block; 132 | 133 | font: 64px/1em @sans; 134 | color: @main; 135 | 136 | width: 0.5em; 137 | height: 1em; 138 | 139 | top: 50%; 140 | 141 | right: 100%; 142 | margin-top: -0.5em; 143 | } 144 | 145 | &:before { 146 | -webkit-animation: widerleft 3s infinite; 147 | -moz-animation: widerleft 3s infinite; 148 | -o-animation: widerleft 3s infinite; 149 | animation: widerleft 3s infinite; 150 | } 151 | 152 | &:after { 153 | content: "\\00BB"; 154 | right: auto; 155 | left: 100%; 156 | 157 | -webkit-animation: widerright 3s infinite; 158 | -moz-animation: widerright 3s infinite; 159 | -o-animation: widerright 3s infinite; 160 | animation: widerright 3s infinite; 161 | } 162 | 163 | p { 164 | color: @white; 165 | text-align: center; 166 | padding-top: 0.3em; 167 | font: 20px/1em @sans; 168 | margin-bottom: 0; 169 | .transition; 170 | } 171 | 172 | span { 173 | color: @white; 174 | font: 300 102px/1em @sans-condensed; 175 | .transition; 176 | } 177 | 178 | .signed { 179 | font-family: @sans-condensed; 180 | font-size: 42px; 181 | margin-top: 1.5em; 182 | width: 100%; 183 | } 184 | } 185 | 186 | // IE 187 | &.ie { 188 | padding-left: 2em; 189 | padding-right: 2em; 190 | 191 | p { 192 | &.one.ie, 193 | &.two.ie { display: block; } 194 | } 195 | } 196 | 197 | &.homepage { 198 | p { 199 | &.one.homepage, 200 | &.two.homepage { display: block; } 201 | } 202 | } 203 | 204 | // RWD 205 | &.rwd { 206 | p { 207 | &.one.rwd, 208 | &.two.rwd { display: block; } 209 | } 210 | } 211 | } 212 | } 213 | 214 | 215 | 216 | //****************************************************************************/ 217 | // Responsive 218 | //****************************************************************************/ 219 | @media screen and (max-width: 600px) { 220 | .pb-responsive-overlay { 221 | .pb-message-wrapper { 222 | height: 400px; 223 | width: 400px; 224 | margin-left: -200px; 225 | 226 | h1 { font-size: 62px; } 227 | 228 | p { 229 | font-size: 14px; 230 | line-height: 1.25em; 231 | } 232 | 233 | p.signed { font-size: 28px; } 234 | 235 | .pb-pixel-counter { 236 | height: 160px; 237 | width: 160px; 238 | bottom: 55px; 239 | 240 | &:before, &:after { font-size: 48px; } 241 | 242 | p { font-size: 16px; } 243 | 244 | span { font-size: 82px; } 245 | 246 | .signed { 247 | margin-top: 1.25em; 248 | font-size: 38px; 249 | } 250 | } 251 | } 252 | } 253 | } 254 | @media screen and (max-width: 480px) { 255 | .pb-responsive-overlay { 256 | .pb-message-wrapper { 257 | padding: 5px 1em; 258 | height: 300px; 259 | width: 300px; 260 | margin-left: -150px; 261 | 262 | h1 { 263 | font-size: 42px; 264 | margin-bottom: 0; 265 | } 266 | 267 | p { 268 | font-size: 12px; 269 | line-height: 1.2em; 270 | } 271 | 272 | p.signed { font-size: 22px; } 273 | 274 | .pb-pixel-counter { 275 | height: 135px; 276 | width: 135px; 277 | bottom: 25px; 278 | 279 | &:before, &:after { font-size: 32px; } 280 | 281 | p { font-size: 16px; } 282 | 283 | span { font-size: 62px; } 284 | 285 | .signed { 286 | margin-top: 1.5em; 287 | font-size: 30px; 288 | } 289 | } 290 | } 291 | } 292 | } 293 | 294 | 295 | 296 | //****************************************************************************/ 297 | // Keyframes 298 | //****************************************************************************/ 299 | /* widerleft */ 300 | @-webkit-keyframes widerleft { 301 | 0, 100% { 302 | right: 100%; 303 | } 304 | 50% { 305 | right: 105%; 306 | } 307 | } 308 | @-moz-keyframes widerleft { 309 | 0, 100% { 310 | right: 100%; 311 | } 312 | 50% { 313 | right: 105%; 314 | } 315 | } 316 | @-o-keyframes widerleft { 317 | 0, 100% { 318 | right: 100%; 319 | } 320 | 50% { 321 | right: 105%; 322 | } 323 | } 324 | @keyframes widerleft { 325 | 0, 100% { 326 | right: 100%; 327 | } 328 | 50% { 329 | right: 105%; 330 | } 331 | } 332 | 333 | /* widerright */ 334 | @-webkit-keyframes widerright { 335 | 0, 100% { 336 | left: 100%; 337 | } 338 | 50% { 339 | left: 105%; 340 | } 341 | } 342 | @-moz-keyframes widerright { 343 | 0, 100% { 344 | left: 100%; 345 | } 346 | 50% { 347 | left: 105%; 348 | } 349 | } 350 | @-o-keyframes widerright { 351 | 0, 100% { 352 | left: 100%; 353 | } 354 | 50% { 355 | left: 105%; 356 | } 357 | } 358 | @keyframes widerright { 359 | 0, 100% { 360 | left: 100%; 361 | } 362 | 50% { 363 | left: 105%; 364 | } 365 | } 366 | 367 | /* Pulse */ 368 | @-webkit-keyframes pulse { 369 | 0, 100% { 370 | background-color: darken(@main, 10%); 371 | } 372 | 50% { 373 | background-color: @main; 374 | } 375 | } 376 | @-moz-keyframes pulse { 377 | 0, 100% { 378 | background-color: darken(@main, 10%); 379 | } 380 | 50% { 381 | background-color: @main; 382 | } 383 | } 384 | @-o-keyframes pulse { 385 | 0, 100% { 386 | background-color: darken(@main, 10%); 387 | } 388 | 50% { 389 | background-color: @main; 390 | } 391 | } 392 | @keyframes pulse { 393 | 0, 100% { 394 | background-color: darken(@main, 10%); 395 | } 396 | 50% { 397 | background-color: @main; 398 | } 399 | } 400 | 401 | 402 | 403 | //****************************************************************************/ 404 | // Mixins 405 | //****************************************************************************/ 406 | /* Transition */ 407 | .transition(@arg: all 300ms) { 408 | -webkit-transition: @arg; 409 | -moz-transition: @arg; 410 | -o-transition: @arg; 411 | transition: @arg; 412 | } 413 | 414 | /* Box Shadow */ 415 | .box-shadow(@arguments: @box-shadow) { 416 | -webkit-box-shadow: @arguments; 417 | -moz-box-shadow: @arguments; 418 | box-shadow: @arguments; 419 | } 420 | 421 | /* Box Sizing */ 422 | .box-sizing(@sizing: border-box) { 423 | -webkit-box-sizing: @sizing; 424 | -moz-box-sizing: @sizing; 425 | -ms-box-sizing: @sizing; 426 | box-sizing: @sizing; 427 | } 428 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ProjectBlocker", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "grunt-cli": "latest", 6 | "grunt-contrib-uglify": "latest", 7 | "grunt-contrib-less": "latest", 8 | "grunt-contrib-watch": "latest", 9 | "grunt-contrib-clean": "latest", 10 | "grunt-contrib-cssmin": "latest" 11 | }, 12 | "devDependencies": { 13 | "grunt": "^0.4.5", 14 | "grunt-contrib-concat": "^0.5.0", 15 | "grunt-contrib-connect": "^0.9.0", 16 | "grunt-contrib-jshint": "^0.11.0", 17 | "grunt-contrib-rename": "0.0.3", 18 | "grunt-csstojs": "^0.2.0", 19 | "grunt-html2str": "0.0.1", 20 | "grunt-mkdir": "^0.1.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/jquery.projectblocker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ProjectBlocker.js 3 | * ================= 4 | * A handy jQuery solution for blocking responsive, IE, 5 | * or incomplete bits from being seen while in development. 6 | * 7 | * Version: v1.0.0 8 | * Release: February 07, 2015 9 | * Site: http://github.com/mike-zarandona/ProjectBlocker 10 | * Author: Mike Zarandona | http://twitter.com/mikezarandona 11 | **/ 12 | 13 | ;(function($) { 14 | 15 | var defaults = { 16 | responsive: 'hide', 17 | minWidth: 0, 18 | 19 | homepage: 'show', 20 | homepageSelector: null, 21 | 22 | ie: 'hide' 23 | }; 24 | 25 | 26 | $.projectBlocker = function(options) { 27 | 28 | options = $.extend({}, defaults, options); 29 | 30 | var mobile = (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) ? true : false, 31 | blocked = false, // watch for block status and hold site parameter 32 | siteVar, // holds the value of `getURLParameter` 33 | lsKey, // holds the value of the localstorage developer mode key value pair 34 | 35 | $head = $('head'), // site head 36 | $body = $('body') 37 | ; 38 | 39 | // Add Google font and the styles to the of the document 40 | $head 41 | .append('') 42 | .append('') 43 | .append('') 44 | ; 45 | 46 | // If the viewport meta doesn't exist in the on mobile append it 47 | if ( mobile ) { 48 | if ( $('meta[name=viewport]').length === 0 ) { 49 | $head.append(''); 50 | } 51 | } 52 | 53 | // Increment width to make the math a bit easier 54 | options.minWidth++; 55 | 56 | 57 | /** 58 | * TIME TO DO STUFF 59 | **/ 60 | // Check URL parameter for `/?dev=off` 61 | if ( getURLParameter('dev') == 'off' ) { 62 | if ( testLocalStorage() ) { 63 | notifyTheConsole(0); 64 | localStorage.clear(); 65 | } 66 | } 67 | 68 | // Grab the hostname to enable `/?dev=true` 69 | if ( testLocalStorage() ) { 70 | lsKey = localStorage.getItem( 'PB-' + document.location.hostname ); 71 | 72 | // Alert the user that dev mode is stil on 73 | if ( lsKey == 'true' ) { 74 | notifyTheConsole(1); 75 | } 76 | } 77 | 78 | // Block message ONLY if dev mode is not on, and localStorage item is not set 79 | if ( (getURLParameter('dev') != 'true') && (lsKey != 'true') ) { 80 | 81 | // If we're blocking internet explorer 82 | if ( options.ie == 'hide' ) { 83 | // IE 11 84 | var isIE11 = !!navigator.userAgent.match(/Trident.*rv\:11\./); 85 | if ( isIE11 ) { 86 | blockerBot5000('ie'); 87 | } 88 | 89 | // IE <= 10 90 | if ( /*@cc_on!@*/false ) { 91 | blockerBot5000('ie'); 92 | } 93 | } 94 | 95 | 96 | // If we're blocking the homepage 97 | if ( (options.homepage == 'hide') && (!blocked) ) { 98 | if ( $(options.homepageSelector).length > 0 ) { 99 | blockerBot5000('homepage'); 100 | } 101 | } 102 | 103 | 104 | // If we're blocking responsive design 105 | if ( (options.responsive == 'hide') && (!blocked) ) { 106 | blockerBot5000('rwd'); 107 | } 108 | } 109 | else { 110 | if ( testLocalStorage() ) { 111 | // set the localStorage token to let in devs 112 | localStorage.setItem('PB-' + document.location.hostname, 'true'); 113 | } 114 | } 115 | 116 | 117 | 118 | function blockerBot5000(blockType) { 119 | 120 | // Add overlay content to the 121 | $body.append(pbOverlayDOM); 122 | 123 | var $overlay = $('.pb-responsive-overlay'), 124 | $msgWrapper = $('.pb-message-wrapper'), 125 | $pixelCtr = $('.pb-pixel-counter') 126 | ; 127 | 128 | 129 | // IE 130 | if ( blockType == 'ie' ) { 131 | // set the min width on the `` 132 | $body.css( 'min-width', options.minWidth + 'px' ); 133 | 134 | // Move the signature into the orange circle 135 | $pixelCtr.html( $('.pb-message-wrapper .signed') ); 136 | 137 | // engage the overlay 138 | $overlay.addClass( 'block no-arrows' ); 139 | $msgWrapper.addClass('ie'); 140 | 141 | // set the "blocked" flag 142 | blocked = true; 143 | } 144 | 145 | // Homepage 146 | else if ( blockType == 'homepage' ) { 147 | // set the min width on the ` 148 | $body.css( 'min-width', options.minWidth + 'px' ); 149 | 150 | // Move the signature into the orange circle 151 | $pixelCtr.html( $('.pb-message-wrapper .signed') ); 152 | 153 | // engage the overlay 154 | $overlay.addClass( 'block no-arrows' ); 155 | $msgWrapper.addClass('homepage'); 156 | 157 | // set the "blocked" flag 158 | blocked = true; 159 | } 160 | 161 | // Responsive 162 | else if ( blockType == 'rwd' ) { 163 | // type the message wrapper to `rwd` 164 | $msgWrapper.addClass('rwd'); 165 | 166 | // If the window width is less than our target width OR is a mobile device, show the overlay on load 167 | if ( (window.innerWidth < options.minWidth) || (mobile) ) { 168 | // set the min width on the `` 169 | $body.css('min-width', options.minWidth + 'px'); 170 | 171 | // set the "pixels left to go" 172 | $('.pb-pixel-counter span').html(options.minWidth - window.innerWidth); 173 | 174 | // engage the overlay 175 | $overlay.addClass('show'); 176 | } 177 | 178 | // Bind to the window.resize event 179 | $(window).on('resize', function() { 180 | if ( window.innerWidth < options.minWidth ) { 181 | // set the min width on the `` 182 | $body.css('min-width', options.minWidth + 'px'); 183 | 184 | // engage the overlay 185 | $overlay.addClass('show'); 186 | 187 | // update the pixel counter 188 | $('.pb-pixel-counter span').html(options.minWidth - window.innerWidth); 189 | } 190 | else { 191 | // remove the min width on the ` 192 | $body.css('min-width', '0'); 193 | 194 | // disengage the overlay 195 | $overlay.removeClass('show'); 196 | } 197 | }); 198 | } 199 | } 200 | 201 | 202 | 203 | // A test to see if localStorage and sessionStorage & error handling 204 | function testLocalStorage() { 205 | if ( typeof(Storage) !== void(0) ) { return true; } 206 | else { 207 | notifyTheConsole(2); 208 | return false; 209 | } 210 | } 211 | 212 | 213 | 214 | // Retrieve URL parameters 215 | function getURLParameter(name) { 216 | name = name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]"); 217 | var regexS = "[\\?&]"+name+"=([^&#]*)"; 218 | var regex = new RegExp( regexS ); 219 | var results = regex.exec( window.location.href ); 220 | if( results === null ) 221 | return ""; 222 | else 223 | return results[1]; 224 | } 225 | 226 | 227 | 228 | // console notifier 229 | function notifyTheConsole(type) { 230 | if ( type === 0 ) { 231 | console.info('ProjectBlocker: Developer Mode OFF.'); 232 | } 233 | else if ( type == 1 ) { 234 | console.info('ProjectBlocker: Developer Mode ON.'); 235 | } 236 | else if ( type == 2 ) { 237 | console.error('ProjectBlocker ERROR: localStorage NOT supported - Developer Mode will not persist on navigation.'); 238 | } 239 | } 240 | }; 241 | })(jQuery); 242 | --------------------------------------------------------------------------------