diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b755a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*node_modules* +*.DS_Store* diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..6730597 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +.travis.yml +TODO.md +RELEASE-CHECKLIST.md \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c4baaea --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - "0.10" + - "0.11" +script: ./bin/headstart.js +branches: + only: + - master diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1308fb7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Florian Vanthuyne + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index b418b4b..784fdcd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,42 @@ -Boilerplate 0.2 -=============== +# [Headstart](website-url), an automated front-end setup -An opinionated boilerplate/workflow build on modular snippets, including [Sass](http://sass-lang.com/), [Compass](http://compass-style.org/), [Respond](https://github.com/scottjehl/Respond), [Require](http://requirejs.org/), ... with a mobile-first approach. It's a collection of snippets & best practices combined to a personal workflow, with flexible re-usability and copy-paste-whatever-you-need in mind. Works great as a framework within [CodeKit](http://incident57.com/codekit/), but that's just a personal preference. - -Feedback, questions, ... -Get in touch [@gwenvanhee](http://www.twitter.com/gwenvanhee) \ No newline at end of file +> Headstart is an all-in-one task runner that frees front-end developers of the little worries that come along with modern web development. If you ever wanted to use tools like [Grunt](http://gruntjs.com/) or [Gulp](http://gulpjs.com/), but found the configuration too troublesome, you will probably like this pre-configured setup better. + +[![NPM version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Gitter][gitter-image]][gitter-url] + +## Documentation + + - [Getting started][getting-started-url] + - [Base Setup][base-setup-url] + - [Upgrading][ugrading-url] + +## ♥ Feedback + +What did you like? What didn't you like? Did you get stuck somewhere? Where the docs easy to follow, or did you give up at a certain point? + +This is a one-man project, so some approaches might be personated. Nevertheless, Headstart is meant to be used by other people as well, so your feedback is very valuable! + +[Mail me anything at all](mailto:hello@flovan.me) or [add an issue][issues-url]. + +## Updates + +For all updates, follow [@headstartio][twitter-url] on Twitter. +Changes can be found on [the changelog page][changelog-url]. + +[website-url]: http://headstart.io +[getting-started-url]: http://headstart.io/installation +[base-setup-url]: http://headstart.io/base-setup +[changelog-url]: http://www.headstart.io/changelog +[ugrading-url]: http://headstart.io/upgrading-guide +[twitter-url]: https://twitter.com/headstartio +[issues-url]: https://github.com/flovan/headstart/issues +[npm-url]: https://npmjs.org/package/headstart +[npm-image]: https://badge.fury.io/js/headstart.svg +[travis-url]: https://travis-ci.org/flovan/headstart +[travis-image]: https://travis-ci.org/flovan/headstart.svg +[downloads-url]: https://github.com/flovan/headstart +[downloads-image]: http://img.shields.io/npm/dm/headstart.svg +[david-url]: https://david-dm.org/flovan/headstart +[david-image]: https://david-dm.org/flovan/headstart.png?theme=shields.io +[gitter-url]: https://gitter.im/flovan/headstart?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge +[gitter-image]: https://badges.gitter.im/Join%20Chat.svg diff --git a/RELEASE-CHECKLIST.md b/RELEASE-CHECKLIST.md new file mode 100644 index 0000000..bb4b96c --- /dev/null +++ b/RELEASE-CHECKLIST.md @@ -0,0 +1,43 @@ +## Release checklist + +A list of things that need to work for each and every release. + +### Initialising + +- [ ] Boilerplate files have been updated and packaged into a release +- [ ] The latest boilerplate release can be scaffolded through `hs init` *and* `headstart init` +- [ ] Files can be served through the init +- [ ] A browser can be opened from the init +- [ ] An editor can be opened from the init + +### CLI testing + +- [ ] A build is successfull through `hs build` +- [ ] A production build is success through `hs build --p` *and* `hs build --production` +- [ ] Files can be served in development through `hs build --s` *and* `hs build --serve` +- [ ] Files can be served in production through `hs build --s --p` *and* `hs build --serve --production` +- [ ] A browser can be opened through `hs build --s --o` *and* `hs build --serve --open` +- [ ] A browser can not be opened without `--s` +- [ ] An editor can be opened through `hs build --e` *and* `hs build --edit` *and* `hs build --s --e` *and* `hs build --s --edit` +- [ ] A tunnel can be initiated through `hs build --s --t` *and* `hs build --s --tunnel` +- [ ] A custom tunnel can be initiated through `hs build --s --t=bla` *and* `hs build --s --tunnel=bla` and returns `bla.localtunnel.me` (or something) when available +- [ ] Google PSI can be initiated through `hs build --s --t --psi` +- [ ] The "mobile" PSI strategy can be set through `hs build --s --t --psi --strategy=mobile` +- [ ] Google PSI can not be initiated without both `--s` and `--t` + +### Development + +- [ ] JS files get injected +- [ ] Changes to JS files reload the page +- [ ] Added/deleted JS files reload the page and update the injected files +- [ ] CSS files get injected +- [ ] Changes to CSS files update the page +- [ ] Added/deleted CSS files reload the page and update the injected files +- [ ] Images get copied over +- [ ] Changes to images trigger a reload + +### Production + +- [ ] A `.favicon` is generated in the root +- [ ] A `.htaccess` is generated in the root +- [ ] All `./misc` files are copied over to the root \ No newline at end of file diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..5ff4346 --- /dev/null +++ b/TODO.md @@ -0,0 +1,71 @@ +### TODO's: + + - [ ] Fix crash when missing `// requires` file is found + - [ ] Adding new view js files doesn't seem to add them to gaze + +### A list of things to explore: + + - [ ] Think about fixed size columns for eg ads + - [ ] Try to have revisioned images, even though updating references in other files will be hard (https://github.com/smysnk/gulp-rev-all, maybe https://www.npmjs.org/package/gulp-hash/ + https://www.npmjs.org/package/gulp-hash-references/) + - [ ] Watch changes on config and folders like fonts/video, and rebuild (https://github.com/leny/gulp-supervisor & https://github.com/JacksonGariety/gulp-nodemon & https://www.npmjs.org/package/keepup/) + - [ ] See if Commander is a better alternative to LiftOff (https://github.com/visionmedia/commander.js) + - [ ] Try replacing gulp-inject with gulp-include-source (https://www.npmjs.org/package/gulp-include-source/) + - [ ] See if scripts tasks can be made faster with gulp-remember (https://github.com/ahaurw01/gulp-remember) + - [ ] Maybe do something with icon fonts from SVG files (https://www.npmjs.org/package/gulp-fontcustom/ or https://github.com/nfroidure/gulp-iconfont or https://github.com/nfroidure/gulp-svgicons2svgfont) + - [ ] Make it possible to use LESS (https://www.npmjs.org/package/gulp-less/) + - [ ] Make it possible to use Stylus (https://www.npmjs.org/package/gulp-stylus/) + - [ ] Maybe replace some CSS processing modules with gulp-pleeease (https://www.npmjs.org/package/gulp-pleeease/) + - [ ] Try having critical css inlined (http://css-tricks.com/authoring-critical-fold-css/ & https://github.com/pocketjoso/penthouse/#as-a-node-module OR https://github.com/filamentgroup/criticalcss) + - [ ] Use SassDoc (https://github.com/SassDoc/gulp-sassdoc) + - [ ] Split up gulpfile into task files (https://github.com/whitneyit/gulp-taskify or https://www.npmjs.org/package/gulp-hub/) + - [ ] Remove deleted / renamed files from export folder with gulp-sync-files (https://www.npmjs.org/package/gulp-sync-files/) + - [ ] Replace Ender by Cash when it gets out of alpha (https://github.com/kenwheeler/cash) + - [ ] Check out HeadJS (http://headjs.com) + - [ ] Implement gulp-foreach (https://www.npmjs.org/package/gulp-foreach/) + - [ ] Make sure a key can be used with PSI (without any uncaught TypeError) + - [ ] Simpler watch setup > https://gist.github.com/Snugug/2dc9ff47ce4b4acb28f6 + + + ### Take a look at these plugins also + + - https://www.npmjs.org/package/del/ instead of gulp-rimraf (will prolly have to use https://www.npmjs.org/package/gulp-filenames) + - CDN Solution https://www.npmjs.org/package/gulp-cdnizer/ + - https://www.npmjs.org/package/gulp-log-capture + - https://www.npmjs.org/package/gulp-static-handlebars + - https://www.npmjs.org/package/gulp-if-else + - https://www.npmjs.org/package/gulp-headerfooter + - https://www.npmjs.org/package/gulp-htmlrefs OR https://www.npmjs.org/package/gulp-rev-replace + - https://www.npmjs.org/package/favicons + +### Done + + - [x] Fix reloading when a layout/partial changes + - [x] Find a better/smarter templating system https://www.npmjs.org/package/gulp-file-insert/ + - [x] Find better (smaller, dep-less) way of stripping comments from --production HTML + - [x] Allow custom repo's to be set for scaffolding + - [x] Fix sass and htmlmin error crashes + - [x] Add W3C validation option to config (https://www.npmjs.org/package/gulp-w3cjs/) + - [x] Try out revisions to leverage cache control (https://github.com/sindresorhus/gulp-rev) + - [x] Generate a cache manifeset for --production (https://www.npmjs.org/package/gulp-manifest/ + http://diveintohtml5.info/offline.html) + - [x] Replace livereloading with browser-sync (https://github.com/shakyShane/browser-sync through http://shakyshane.com/gulpjs-sass-browsersync-ftw/) + - [x] ^ Fix logging by gulp-connect (~~muting https://www.npmjs.org/package/mute-stream~~) + - [x] Auto-check for updates (~~http://stackoverflow.com/questions/20686244/install-programmatically-a-npm-package-providing-its-version and http://stackoverflow.com/questions/11949419/nodejs-npm-show-latest-version-of-a-module~~ https://github.com/yeoman/update-notifier) + - [x] Make box-sizing work through inherit (http://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice) + - [x] Find a less crude way of muting module output through gulp-util + - [x] Put Liftoff logo on website (https://www.npmjs.org/package/liftoff) + - [x] Make HTML minifier options configurable through `config.json` + - [x] Properly test gulp-combine-media-queries (Result: saves a few KB's, enabling by default in boilerplate v1.1.1) + - [ ] ~~Use a different minifier (https://www.npmjs.org/package/gulp-compressor/ or https://www.npmjs.org/package/gulp-minifier/)~~ + - [ ] ~~Check out csscss (https://www.npmjs.org/package/gulp-csscss/)~~ + - [x] Properly test Uncss + - [x] Pass gulp-ruby-sass errors instead of uncss notification + - [x] Remove ender and underscore map from underscore.js + - [x] Turn aliasing into state, and extend to doc/button/form module + - [x] Fix url in update notice + - [x] Fix jshint logs appearing in the middle of the progressbar + - [x] Dry out modules + - [x] Drop `open` in favour of opening the browser through `browsersync` + - [x] A build starting with a Sass error will result in pages without (a) css file(s) + - [x] Disable (and warn about disabling of) w3c validation when not ".html" + - [x] Re-add `open` because openEditor won't work otherwise.. + \ No newline at end of file diff --git a/bin/headstart.js b/bin/headstart.js new file mode 100755 index 0000000..8f44651 --- /dev/null +++ b/bin/headstart.js @@ -0,0 +1,190 @@ +#!/usr/bin/env node +'use strict'; + +// To see an extended Error Stack Trace, uncomment +// Error.stackTraceLimit = 9000; + +// REQUIRES ------------------------------------------------------------------- +// +// Note: Gulp related requires are made further down to speed up the first +// part of this script + +var + path = require('path'), + fs = require('fs'), + chalk = require('chalk'), + _ = require('lodash'), + + pkg = require('../package.json'), + Liftoff = require('liftoff'), + updateNotifier = require('update-notifier'), + argv = require('minimist')(process.argv.slice(2)), + gulp, + gulpFile +; + +// CLI CONFIGURATION ---------------------------------------------------------- +// + +var cli = new Liftoff({ + name: 'headstart' +}); + +// CHECK FOR UPDATES ---------------------------------------------------------- +// + +var notifier = updateNotifier({ + packageName: pkg.name, + packageVersion: pkg.version +}); + +if (notifier.update) { + // Inlined from the update-notifier source for more control + console.log( + chalk.yellow('\n\n┌──────────────────────────────────────────┐\n|') + + chalk.white(' Update available: ') + + chalk.green(notifier.update.latest) + + chalk.grey(' (current: ' + notifier.update.current + ') ') + + chalk.yellow('|\n|') + + chalk.white(' Instructions can be found on: ') + + chalk.yellow('|\n|') + + chalk.magenta(' http://headstart.io/upgrading-guide ') + + chalk.yellow('|\n') + + chalk.yellow('└──────────────────────────────────────────┘\n') + ); +} + +// LAUNCH CLI ----------------------------------------------------------------- +// + +cli.launch({}, launcher); + +function launcher (env) { + + var + versionFlag = argv.v || argv.version, + infoFlag = argv.i || argv.info || argv.h || argv.help, + + allowedTasks = ['init', 'build'], + task = argv._, + numTasks = task.length + ; + + // Check for version flag + if (versionFlag) { + logHeader(pkg); + process.exit(0); + } + + // Log info if no tasks are passed in + if (!numTasks) { + logInfo(pkg); + process.exit(0); + } + + // Warn if more than one tasks has been passed in + if (numTasks > 1) { + console.log(chalk.red('\nOnly one task can be provided. Aborting.\n')); + logTasks(); + process.exit(0); + } + + // We are now sure we only have 1 task + task = task[0]; + + // Print info if needed + if(infoFlag) { + logInfo(pkg); + process.exit(0); + } + + // Check if task is valid + if (_.indexOf(allowedTasks, task) < 0) { + console.log(chalk.red('\nThe provided task "' + task + '" was not recognized. Aborting.\n')); + logTasks(); + process.exit(0); + } + + // Change directory to where Headstart was called from + if (process.cwd() !== env.cwd) { + process.chdir(env.cwd); + console.log(chalk.cyan('Working directory changed to', chalk.magenta(env.cwd))); + } + + // Require gulp assets + gulp = require('gulp'); + gulpFile = require(path.join(path.dirname(fs.realpathSync(__filename)), '../gulpfile.js')); + + // Start the task through Gulp + process.nextTick(function () { + gulp.start.apply(gulp, [task]); + }); +} + +// HELPER FUNCTIONS ----------------------------------------------------------- +// + +function logInfo (pkg) { + logHeader(pkg); + logTasks(); +} + +function logHeader (pkg) { + console.log( + chalk.cyan( + '\n' + + '| | | |\n' + + '|---.,---.,---.,---|,---.|--- ,---.,---.|---\n' + + '| ||---\',---|| |`---.| ,---|| |\n' + + '` \'`---\'`---^`---\'`---\'`---\'`---^` `---\'\n\n' + ) + + chalk.cyan.inverse('➳ http://headstart.io') + + ' ' + + chalk.yellow.inverse('v' + pkg.version) + '\n' + ); +} + +function logTasks () { + console.log( + chalk.grey.underline('To start a new project, run:\n\n') + + chalk.magenta('headstart init [flags]') + + chalk.grey(' or ') + + chalk.magenta('hs init [flags]\n\n') + + chalk.white('--base ') + + chalk.grey('\t\tUse a custom boilerplate repo, eg. user/repo#branch\n') + ); + console.log( + chalk.grey.underline('To build the project, run:\n\n') + + chalk.magenta('headstart build [flags]') + + chalk.grey(' or ') + + chalk.magenta('hs build [flags]\n\n') + + chalk.white('--s, --serve') + + chalk.grey('\t\tServe the files on a static address\n') + + chalk.white('--o, --open') + + chalk.grey('\t\tOpen up a browser for you (default Google Chrome)\n') + + chalk.white('--e, --edit') + + chalk.grey('\t\tOpen the files in your editor (default Sublime Text)\n') + + chalk.white('--p, --production') + + chalk.grey('\tMake a production ready build\n') + + chalk.white('--t, --tunnel') + + chalk.grey('\t\tTunnel your served files to the web (requires --serve)\n') + + chalk.white('--psi') + + chalk.grey('\t\t\tRun PageSpeed Insights (requires --serve and --tunnel)\n') + + //chalk.white('--key ') + + //chalk.grey('\t\tOptional, an API key for PSI\n') + + chalk.white('--strategy ') + + chalk.grey('\tRun PSI in either "desktop" (default) or "mobile" mode\n\n') + + chalk.white('--verbose') + + chalk.grey('\t\tOutput extra information while building\n') + ); + console.log( + chalk.grey.underline('For information, run:\n\n') + + chalk.magenta('headstart [flags]') + + chalk.grey(' or ') + + chalk.magenta('hs [flags]\n\n') + + chalk.white('--i, --info,\n--h, --help') + + chalk.grey('\t\tPrint out this message\n') + + chalk.white('--v, --version') + + chalk.grey('\t\tPrint out version\n') + ); +} diff --git a/css/desktop.css b/css/desktop.css deleted file mode 100644 index 8ea9a35..0000000 --- a/css/desktop.css +++ /dev/null @@ -1 +0,0 @@ -@charset "utf-8";a:hover,a:active{text-decoration:none} diff --git a/css/ie.css b/css/ie.css deleted file mode 100644 index e63c05c..0000000 --- a/css/ie.css +++ /dev/null @@ -1 +0,0 @@ -@charset "utf-8"; diff --git a/css/mobile.css b/css/mobile.css deleted file mode 100644 index ca6ae4c..0000000 --- a/css/mobile.css +++ /dev/null @@ -1 +0,0 @@ -@charset "utf-8";html,body,div,span,object,iframe,canvas,h1,h2,h3,h4,h5,h6,p,a,img,strong,sub,sup,b,u,i,center,ol,ul,li,form,label,table,tr,td,audio,video{margin:0;padding:0;border:0;outline:none;font-family:inherit;font-size:100%;vertical-align:baseline;-webkit-text-stroke:1px transparent;-webkit-font-smoothing:antialiased;-moz-font-smoothing:antialiased;-o-font-smoothing:antialiased;font-smoothing:antialiased;image-rendering:auto;-ms-interpolation-mode:bicubic;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-touch-action:none}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.clear:before,.clear:after{content:"";display:table}.clear:after{clear:both}.clear{*zoom:1}html{line-height:1;height:100%}body{font-weight:normal;font-style:normal;height:100%}ul,ol{list-style:none}table{border-collapse:collapse;border-spacing:0}a img{border:0}@font-face{font-family:"{{__My awesome font name__}}";src:url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.eot');src:url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.eot?#iefix') format('eot'),url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.woff') format('woff'), url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.ttf') format('truetype'), url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.svg#webfont') format('svg');font-weight:"normal";font-style:"normal"}.trim{position:relative;white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis}.line-clamp{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.break-word{-ms-word-break:break-all;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto}.quotes:before{content:"\201C"}.quotes:after{content:"\201D"}.emphasize:first-letter{font-size:180%;font-weight:bold}.embedded-content{height:0;position:relative;padding-bottom:56.4%;overflow:hidden}.embedded-content iframe,.embedded-content object,.embedded-content embed{width:100%;height:100%;position:absolute;top:0;left:0}.no-popup{-webkit-touch-callout:none}.non-selectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.CSS3Animation{-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-moz-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-ms-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-o-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-webkit-backface-visibility:hidden;-webkit-perspective:1000}.CSS3HardwareAcceleration{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}body{font-family:Helvetica, Arial, Verdana, sans-serif;font-size:16px;min-width:980px}h1{font-size:2.2em;line-height:1.5em}h2{font-size:1.8em;line-height:1.5em}h3{font-size:1.4em;line-height:1.5em}p{font-size:1em;line-height:1.5em}a{text-decoration:underline}hr{height:1px;margin:1.5em 0;padding:0;border:0;border-top:1px solid #CCC;display:block}.smaller{font-size:70%} diff --git a/css/sources/__css3-animations.scss b/css/sources/__css3-animations.scss deleted file mode 100644 index 63b5eea..0000000 --- a/css/sources/__css3-animations.scss +++ /dev/null @@ -1,19 +0,0 @@ -// -// CSS3 ANIMATION MIXIN -------------------------------------------------------------- -// -// Combined Compass mixins to a custom mixin for CSS3 animations -// http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css -// - -@import "compass/css3"; - - -@mixin css3Animation($prop, $time, $easing) { - // enable hardware acceleration - @include experimental("transform", translate3d(0, 0, 0)); - // animate - @include experimental("transition", $prop $time $easing); - // prevent flickering in animation - -webkit-backface-visibility: hidden; - -webkit-perspective: 1000; -} \ No newline at end of file diff --git a/css/sources/__embedded-content.scss b/css/sources/__embedded-content.scss deleted file mode 100644 index 4dd588c..0000000 --- a/css/sources/__embedded-content.scss +++ /dev/null @@ -1,31 +0,0 @@ -// -// EMBEDDED CONTENT MIXIN ------------------------------------------------------------ -// -// Mixin for fluid embedded content (vimeo, youtube, slideshare, ...) @16:9 ratio -// http://amobil.se/2011/11/responsive-embeds -// -// For this mixin to work, use the following HTML-structure: -//
-// Embedded code... -//
-// - -@import "compass/css3"; - - -@mixin embedded-content() { - height: 0; - position: relative; - padding-bottom: 56.4%; // 16:9 ratio = 56.25%, but 56.4% works better with vimeo - overflow: hidden; - - iframe, - object, - embed { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - } -} \ No newline at end of file diff --git a/css/sources/__emphasize-first-character.scss b/css/sources/__emphasize-first-character.scss deleted file mode 100644 index f2ef794..0000000 --- a/css/sources/__emphasize-first-character.scss +++ /dev/null @@ -1,17 +0,0 @@ -// -// EMPHASIZE MIXIN ------------------------------------------------------------------- -// -// Mixin which makes the first character bigger & bold -// Note: doesn't work on inline elements (eg ) -// http://css-tricks.com/almanac/selectors/f/first-letter -// - -@import "compass/css3"; - - -@mixin emphasizeFirstCharacter($size) { - &:first-letter { - font-size: $size; - font-weight: bold; - } -} \ No newline at end of file diff --git a/css/sources/__font-face.scss b/css/sources/__font-face.scss deleted file mode 100644 index df9a77b..0000000 --- a/css/sources/__font-face.scss +++ /dev/null @@ -1,23 +0,0 @@ -// -// FONT-FACE MIXIN ------------------------------------------------------------------- -// -// Extends the Compass mixin so only a font-name & file-name are needed -// http://compass-style.org/reference/compass/css3/font_face -// - -@import "compass/css3"; - - -@mixin fontFace($name, $url) { - @include font-face( - $name, - - font-files( - $url +".woff", - $url +".ttf", - $url +".svg#webfont"), - $url +".eot", - - "normal", "normal" - ); -} \ No newline at end of file diff --git a/css/sources/__line-clamp.scss b/css/sources/__line-clamp.scss deleted file mode 100644 index ccfda3c..0000000 --- a/css/sources/__line-clamp.scss +++ /dev/null @@ -1,20 +0,0 @@ -// -// LINE-CLAMP MIXIN ------------------------------------------------------------------ -// -// Mixin to trim a multiline text-element and add ellipsis (...) -// Note: only works in Webkit browsers & Safari -// http://www.css-101.org/articles/line-clamp/line-clamp_for_non_webkit-based_browsers.php -// - -@import "compass/css3"; - - -@mixin line-clamp($lines) { - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-box-orient: vertical; - - // number of lines to show - -webkit-line-clamp: $lines; -} \ No newline at end of file diff --git a/css/sources/__quotes.scss b/css/sources/__quotes.scss deleted file mode 100644 index a07a851..0000000 --- a/css/sources/__quotes.scss +++ /dev/null @@ -1,14 +0,0 @@ -// -// QUOTES MIXIN ---------------------------------------------------------------------- -// -// Mixin to adds "quotes" to text -// http://www.cssbakery.com/2010/12/html-blockquote-element-css-content-and.html -// - -@import "compass/css3"; - - -@mixin quotes { - &:before { content: "\201C"; } - &:after{ content: "\201D"; } -} \ No newline at end of file diff --git a/css/sources/__reset.scss b/css/sources/__reset.scss deleted file mode 100644 index 43576ec..0000000 --- a/css/sources/__reset.scss +++ /dev/null @@ -1,96 +0,0 @@ -// -// CSS RESET ------------------------------------------------------------------------- -// -// Based on HTML5 Boilerplate and Compass CSS Reset -// https://github.com/h5bp/html5-boilerplate -// http://compass-style.org/reference/compass/reset -// - -html, body, div, span, object, iframe, canvas, -h1, h2, h3, h4, h5, h6, p, a, img, -strong, sub, sup, b, u, i, center, -ol, ul, li, -form, label, table, tr, td, -audio, video { - margin: 0; - padding: 0; - border: 0; - outline: none; - font-family: inherit; - font-size: 100%; - vertical-align: baseline; - - // Enable smooth fonts - -webkit-text-stroke: 1px transparent; - -webkit-font-smoothing: antialiased; - -moz-font-smoothing: antialiased; - -o-font-smoothing: antialiased; - font-smoothing: antialiased; - - // Improve image scaling - // https://developer.mozilla.org/nl/docs/CSS/image-rendering - image-rendering: auto; - -ms-interpolation-mode: bicubic; - - // Override the semitransparent color overlay when a user clicks something - // to disable it set value to 'transparent' or 'rgba(0,0,0,0)' - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - - // Prevent iOS text size adjust on focus or after orientation change - // without disabling zoom with the viewport meta-tag - // https://developer.mozilla.org/en-US/docs/CSS/text-size-adjust - -webkit-text-size-adjust: 100%; - -moz-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - - // Enable javascript pointer events on IE Mobile by disabling events in CSS - // http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx - -ms-touch-action: none; -} - -// FIX BROKEN BOX-MODEL -// Note: doesn't work in IE7 (padding is still added to the box width/height) -// https://developer.mozilla.org/en-US/docs/CSS/box-sizing -*, *:before, *:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -// CLEARFIX -// Note: still supports IE7 -// http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php -.clear:before, .clear:after { - content: ""; - display: table; -} -.clear:after { - clear: both; -} -.clear { - *zoom: 1; -} - -// -// COMMON STYLES --------------------------------------------------------------------- -// - -html { - line-height: 1; - height: 100%; -} -body { - font-weight: normal; - font-style: normal; - height: 100%; -} -ul, ol { - list-style: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -a img { - border: 0; -} \ No newline at end of file diff --git a/css/sources/__retina-support.scss b/css/sources/__retina-support.scss deleted file mode 100644 index db33367..0000000 --- a/css/sources/__retina-support.scss +++ /dev/null @@ -1,21 +0,0 @@ -// -// RETINA SUPPORT MIXIN -------------------------------------------------------------- -// -// CSS support for high pixel density devices -// Note: this will not prevent assets getting loaded 2x (normal + hdpi) -// http://www.sitepoint.com/support-retina-displays -// http://www.brettjankord.com/2012/11/28/cross-browser-retinahigh-resolution-media-queries -// - -@import "compass/css3"; - - -@mixin retinaSupport { - @media - only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and (min-resolution: 192dpi) { - - @content; - - } -} \ No newline at end of file diff --git a/css/sources/__trim.scss b/css/sources/__trim.scss deleted file mode 100644 index c877bd0..0000000 --- a/css/sources/__trim.scss +++ /dev/null @@ -1,18 +0,0 @@ -// -// TRIM MIXIN ------------------------------------------------------------------------ -// -// Mixin to trim a text-element and add ellipsis (...) -// Note: only works with a fixed width & single line text -// http://www.electrictoolbox.com/ellipsis-html-css -// - -@import "compass/css3"; - - -@mixin trim { - position: relative; - white-space: nowrap; - overflow: hidden; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; -} \ No newline at end of file diff --git a/css/sources/desktop.scss b/css/sources/desktop.scss deleted file mode 100644 index 9bbbd66..0000000 --- a/css/sources/desktop.scss +++ /dev/null @@ -1,133 +0,0 @@ -// -// CSS FOR TABLET + DESKTOP ---------------------------------------------------------- -// -// Dependencies: Sass + Compass -// http://sass-lang.com -// http://compass-style.org -// - -@charset "utf-8"; -@import "compass/css3"; - -@import "__retina-support"; - - -// MEDIA QUERIES -// Default: mobile-portrait (override/add some desktop specific styles) -$tablet-portrait : 768px; -$tablet-landscape : 1024px; -$desktop : 1025px; - - -// BASE 64 ENCODED IMAGES -// Note: Encoded images must be smaller then 32kb (or IE won't show them) -// http://www.askapache.com/online-tools/base64-image-converter -// background: url(data:image/__typegoeshere__;base64,____); - - -// COMPASS VENDOR-PREFIXES -// @include experimental("{{__PROPERTY__}}", {{__VALUE__}}, not -webkit, not -moz, -o, -ms, -khtml, official); - - -// USING REM-UNITS vs EM-UNITS -// Not integrating this for the moment, but it's something to keep in mind -// rem-units are supported by all major browsers (except IE7, IE8) -// http://drublic.de/blog/rem-fallback-sass-less -// http://caniuse.com/#search=rem - - -// -// GENERAL --------------------------------------------------------------------------- -// -// Add some desktop specific styles here when working with responsive/fluid design -// In other words add your :hover states here (there not supported on mobile) -// - -html { - -} - -a:hover, -a:active { - text-decoration: none; -} - - -// Add .no-touch class to the HTML tag if touchEvents are not supported -// This way we can disable :hover states on touch-devices -// Note: javascript will add it for you - see js/sources/app.js -.no-touch { - -} - - - - - - - - -// -// TABLET PORTRAIT ------------------------------------------------------------------- -// - -@media screen and (min-width: $tablet-portrait) { - -} - - - - - - - - -// -// TABLET LANDSCAPE ------------------------------------------------------------------ -// - -@media screen and (min-width: $tablet-landscape) { - -} - - - - - - - - -// -// DESKTOP --------------------------------------------------------------------------- -// - -@media screen and (min-width: $desktop) { - -} - - - - - - - - -// -// RETINA SUPPORT FOR HDPI SCREENS --------------------------------------------------- -// -// Include hdpi images for retina screens here -// Note: if you specify a non-retina image + retina image you'll download 2 images (!) -// If you want to enable fluid/responsive images without loading assets 2 times -// take a look at js/dev/responsiveImages.js -// - -@include retinaSupport() { - -} - - - - - - - diff --git a/css/sources/ie.scss b/css/sources/ie.scss deleted file mode 100644 index c51aa2e..0000000 --- a/css/sources/ie.scss +++ /dev/null @@ -1,117 +0,0 @@ -// -// CSS FOR IE8 + IE7 ----------------------------------------------------------------- -// -// Loads conditionally (doesn't get loaded on modern browsers) -// Dependencies: js/libs/require.js (to enable MediaQueries) -// -// Use regular CSS for IE8 > html { property: value; } -// Prefix with * for IE7 > html { *property: value; } -// -// Dependencies: Sass + Compass -// http://sass-lang.com -// http://compass-style.org -// - -@charset "utf-8"; -@import "compass/css3"; - - -// MEDIA QUERIES -// Default: mobile-portrait -$mobile-landscape : 480px; -$tablet-portrait : 768px; -$tablet-landscape : 1024px; -$desktop : 1025px; - - -// BASE 64 ENCODED IMAGES -// Note: Encoded images must be smaller then 32kb (or IE won't show them) -// http://www.askapache.com/online-tools/base64-image-converter -// background: url(data:image/__typegoeshere__;base64,____); - - -// COMPASS VENDOR-PREFIXES -// @include experimental("{{__PROPERTY__}}", {{__VALUE__}}, not -webkit, not -moz, -o, -ms, -khtml, official); - - -// USING REM-UNITS vs EM-UNITS -// Not integrating this for the moment, but it's something to keep in mind -// rem-units are supported by all major browsers (except IE7, IE8) -// http://drublic.de/blog/rem-fallback-sass-less -// http://caniuse.com/#search=rem - - -// -// GENERAL --------------------------------------------------------------------------- -// - -html { - -} - - - - - - - - -// -// MOBILE LANDSCAPE ------------------------------------------------------------------ -// - -@media screen and (min-width: $mobile-landscape) { - -} - - - - - - - - -// -// TABLET PORTRAIT ------------------------------------------------------------------- -// - -@media screen and (min-width: $tablet-portrait) { - -} - - - - - - - - -// -// TABLET LANDSCAPE ------------------------------------------------------------------ -// - -@media screen and (min-width: $tablet-landscape) { - -} - - - - - - - - -// -// DESKTOP --------------------------------------------------------------------------- -// - -@media screen and (min-width: $desktop) { - -} - - - - - - - diff --git a/css/sources/mobile.scss b/css/sources/mobile.scss deleted file mode 100644 index 3a1e95a..0000000 --- a/css/sources/mobile.scss +++ /dev/null @@ -1,296 +0,0 @@ -// -// CSS FOR SMARTPHONES + SMALLER TABLETS (< 768px) ----------------------------------- -// -// Dependencies: Sass + Compass -// http://sass-lang.com -// http://compass-style.org -// - -@charset "utf-8"; -@import "compass/css3"; - -@import "__reset"; -@import "__font-face"; -@import "__retina-support"; -@import "__trim"; -@import "__line-clamp"; -@import "__quotes"; -@import "__emphasize-first-character"; -@import "__embedded-content"; -@import "__css3-animations"; - - -// MEDIA QUERIES -// Default: mobile-portrait -$mobile-landscape : 480px; - - -// BASE 64 ENCODED IMAGES -// Note: Encoded images must be smaller then 32kb (or IE won't show them) -// http://www.askapache.com/online-tools/base64-image-converter -// background: url(data:image/__typegoeshere__;base64,____); - - -// COMPASS VENDOR-PREFIXES -// @include experimental("{{__PROPERTY__}}", {{__VALUE__}}, not -webkit, not -moz, -o, -ms, -khtml, official); - - -// USING REM-UNITS vs EM-UNITS -// Not integrating this for the moment, but it's something to keep in mind -// rem-units are supported by all major browsers (except IE7, IE8) -// http://drublic.de/blog/rem-fallback-sass-less -// http://caniuse.com/#search=rem - - -// -// CUSTOM WEBFONTS ------------------------------------------------------------------- -// -// A custom webfont needs 4 file-types: .woff, .ttf, .svg, .eot -// All files need to be stored in ../fonts/ -// http://www.fontsquirrel.com/tools/webfont-generator -// - -@include fontFace("{{__My awesome font name__}}", "{{__my-awesome-font-name-(file-name-without-extension)__}}"); - - - - - - - - -// -// HELPERS --------------------------------------------------------------------------- -// - -// TRIM TEXT -// Trims & add ellipsis (...) -// Note: only works with a fixed width & single line text -.trim { - @include trim; -} - -// TRIM MULTILINE TEXT -// Trims & add ellipsis (...) to multiline text -// Note: only works with in Webkit browsers & Safari -.line-clamp { - @include line-clamp(3); -} - -// BREAK WORDS -// Prevent longwordsorurlswithoutspacesfrombreaking your layout -// http://blog.kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css -// http://compass-style.org/reference/compass/css3/hyphenation -.break-word { - @include hyphenation; -} - -// QUOTES -// Adds "quotes" to text -.quotes { - @include quotes; -} - -// EMPHASIZE -// Bigger, bold first character -// Note: doesn't work on inline elements (eg ) -.emphasize { - @include emphasizeFirstCharacter(180%); -} - -// EMBEDDED CONTENT -// Wrapper for fluid embedded content (vimeo, youtube, slideshare, ...) @16:9 ratio -// For this to work, use the following HTML-structure: -//
-// Embedded code... -//
-.embedded-content { - @include embedded-content; -} - -// NO TOUCH CALLOUT -// Prevent a popup menu on mobile devices on touch & hold -// http://davidwalsh.name/webkit-css -.no-popup { - -webkit-touch-callout: none; -} - -// NON-SELECTABLE -// Prevent something from being selected with the mouse/touch -.non-selectable { - @include experimental("user-select", none); -} - -// CSS3 ANIMATIONS -// Mixin example for CSS3 animations -.CSS3Animation { - @include css3Animation(all, 300ms, cubic-bezier(.445, .045, .0355, 1)); -} - -// ENABLE HARDWARE ACCELERATION -// Kick in hardware acceleration (better performance on mobile) -// http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css -.CSS3HardwareAcceleration { - @include experimental("transform", translateZ(0)); -} - - - - - - - - -// -// GENERAL --------------------------------------------------------------------------- -// -// Don't add :hover states here, touch-devices do not support them -// Add/override them in css/desktop.css instead -// - -html { - -} - -body { - font-family: Helvetica, Arial, Verdana, sans-serif; - font-size: 16px; - - // if the viewport meta tag is not included: use min-width for correct - // scaling on orientationchange (IOS default page-width: 980px) - min-width: 980px; -} - -h1 { - font-size: 2.2em; - line-height: 1.5em; -} - -h2 { - font-size: 1.8em; - line-height: 1.5em; -} - -h3 { - font-size: 1.4em; - line-height: 1.5em; -} - -p { - font-size: 1em; - line-height: 1.5em; -} - -a { - text-decoration: underline; -} - -hr { - height: 1px; - margin: 1.5em 0; - padding: 0; - border: 0; - border-top: 1px solid #CCC; - display: block; -} - -.smaller { - font-size: 70%; -} - - - - - - - - -// -// MOBILE LANDSCAPE ------------------------------------------------------------------ -// - -@media screen and (min-width: $mobile-landscape) { - -} - - - - - - - - -// -// RETINA SUPPORT FOR HDPI SCREENS --------------------------------------------------- -// -// Include hdpi images for retina screens here -// Note: if you specify a non-retina image + retina image you'll download 2 images (!) -// If you want to enable fluid/responsive images without loading assets 2 times -// take a look at js/dev/responsiveImages.js -// - -@include retinaSupport() { - -} - - - - - - - - -// FORMS ----------------------------------------------------------------------------- -// styling of input elements is not crossbrowser -// needs additional platform tests -// http://s3.amazonaws.com/37assets/svn/480-custom_forms.html -/* -button, input, select, textarea { - line-height: normal; - font-family: inherit; - font-size: 1.6em; - padding: 5px; - margin: 0; - - border: 1px solid #555; - background: #FFF; - background: -webkit-gradient(linear, left top, left bottom, from(#FFF), to(#CCC)); - - -webkit-appearance: none; - -webkit-box-shadow: 1px 1px 1px #FFF; - - -webkit-border-radius: .5em; - -moz-border-radius: .5em; - border-radius: .5em; -} -input:focus, -select:focus, -textarea:focus { - outline: none; - border: 2px solid #F00; - margin: -1px; -} -textarea { - height: 100px; -} -input[type=checkbox], -input[type=radio] { - width: .9em; - height: .9em; - vertical-align: middle; - -webkit-border-radius: .25em; - } - input[type=radio] { - -webkit-border-radius: 2em; -} -// change color of placeholders -::-webkit-input-placeholder { - color: #F00; -} -:-moz-placeholder { - color: #F00; -} -:-ms-input-placeholder { - color: #F00; -} -*/ \ No newline at end of file diff --git a/css/sources/styles-non-mobile-first.scss b/css/sources/styles-non-mobile-first.scss deleted file mode 100644 index edad304..0000000 --- a/css/sources/styles-non-mobile-first.scss +++ /dev/null @@ -1,346 +0,0 @@ -// -// NON-MOBILE FIRST CSS SETUP -------------------------------------------------------- -// -// Dependencies: Sass + Compass -// http://sass-lang.com -// http://compass-style.org -// - -@charset "utf-8"; -@import "compass/css3"; - -@import "__reset"; -@import "__font-face"; -@import "__retina-support"; -@import "__trim"; -@import "__line-clamp"; -@import "__quotes"; -@import "__emphasize-first-character"; -@import "__embedded-content"; -@import "__css3-animations"; - - -// MEDIA QUERIES -// Default: mobile-portrait -$mobile-landscape : 480px; -$tablet-portrait : 768px; -$tablet-landscape : 1024px; -$desktop : 1025px; - - -// BASE 64 ENCODED IMAGES -// Note: Encoded images must be smaller then 32kb (or IE won't show them) -// http://www.askapache.com/online-tools/base64-image-converter -// background: url(data:image/__typegoeshere__;base64,____); - - -// COMPASS VENDOR-PREFIXES -// @include experimental("{{__PROPERTY__}}", {{__VALUE__}}, not -webkit, not -moz, -o, -ms, -khtml, official); - - -// USING REM-UNITS vs EM-UNITS -// Not integrating this for the moment, but it's something to keep in mind -// rem-units are supported by all major browsers (except IE7, IE8) -// http://drublic.de/blog/rem-fallback-sass-less -// http://caniuse.com/#search=rem - - -// -// CUSTOM WEBFONTS ------------------------------------------------------------------- -// -// A custom webfont needs 4 file-types: .woff, .ttf, .svg, .eot -// All files need to be stored in ../fonts/ -// http://www.fontsquirrel.com/tools/webfont-generator -// - -@include fontFace("{{__My awesome font name__}}", "{{__my-awesome-font-name-(file-name-without-extension)__}}"); - - - - - - - - -// -// HELPERS --------------------------------------------------------------------------- -// - -// TRIM TEXT -// Trims & add ellipsis (...) -// Note: only works with a fixed width & single line text -.trim { - @include trim; -} - -// TRIM MULTILINE TEXT -// Trims & add ellipsis (...) to multiline text -// Note: only works with in Webkit browsers & Safari -.line-clamp { - @include line-clamp(3); -} - -// BREAK WORDS -// Prevent longwordsorurlswithoutspacesfrombreaking your layout -// http://blog.kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css -// http://compass-style.org/reference/compass/css3/hyphenation -.break-word { - @include hyphenation; -} - -// QUOTES -// Adds "quotes" to text -.quotes { - @include quotes; -} - -// EMPHASIZE -// Bigger, bold first character -// Note: doesn't work on inline elements (eg ) -.emphasize { - @include emphasizeFirstCharacter(180%); -} - -// EMBEDDED CONTENT -// Wrapper for fluid embedded content (vimeo, youtube, slideshare, ...) @16:9 ratio -// For this to work, use the following HTML-structure: -//
-// Embedded code... -//
-.embedded-content { - @include embedded-content; -} - -// NO TOUCH CALLOUT -// Prevent a popup menu on mobile devices on touch & hold -// http://davidwalsh.name/webkit-css -.no-popup { - -webkit-touch-callout: none; -} - -// NON-SELECTABLE -// Prevent something from being selected with the mouse/touch -.non-selectable { - @include experimental("user-select", none); -} - -// CSS3 ANIMATIONS -// Mixin example for CSS3 animations -.CSS3Animation { - @include css3Animation(all, 300ms, cubic-bezier(.445, .045, .0355, 1)); -} - -// ENABLE HARDWARE ACCELERATION -// Kick in hardware acceleration (better performance on mobile) -// http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css -.CSS3HardwareAcceleration { - @include experimental("transform", translate3d(0, 0, 0)); -} - - - - - - - - -// -// GENERAL --------------------------------------------------------------------------- -// - -html { - -} - -body { - font-family: Helvetica, Arial, Verdana, sans-serif; - font-size: 16px; - - // If the viewport meta tag is not included: use min-width for correct - // scaling on orientationchange (IOS default page-width: 980px) - min-width: 980px; -} - -h1 { - font-size: 2.2em; - line-height: 1.5em; -} - -h2 { - font-size: 1.8em; - line-height: 1.5em; -} - -h3 { - font-size: 1.4em; - line-height: 1.5em; -} - -p { - font-size: 1em; - line-height: 1.5em; -} - -a { - text-decoration: underline; -} - -hr { - height: 1px; - margin: 1.5em 0; - padding: 0; - border: 0; - border-top: 1px solid #CCC; - display: block; -} - -.smaller { - font-size: 70%; -} - -// Add .no-touch class to the HTML tag if touchEvents are not supported -// This way we can disable :hover states on touch-devices -// Note: javascript will add it for you - see js/sources/app.js -.no-touch { - -} - - - - - - -// -// MOBILE LANDSCAPE ------------------------------------------------------------------ -// - -@media screen and (min-width: $mobile-landscape) { - -} - - - - - - - - -// -// TABLET PORTRAIT ------------------------------------------------------------------- -// - -@media screen and (min-width: $tablet-portrait) { - -} - - - - - - - - -// -// TABLET LANDSCAPE ------------------------------------------------------------------ -// - -@media screen and (min-width: $tablet-landscape) { - -} - - - - - - - - -// -// DESKTOP --------------------------------------------------------------------------- -// - -@media screen and (min-width: $desktop) { - -} - - - - - - - - -// -// RETINA SUPPORT FOR HDPI SCREENS --------------------------------------------------- -// -// Include hdpi images for retina screens here -// Note: if you specify a non-retina image + retina image you'll download 2 images (!) -// If you want to enable fluid/responsive images without loading assets 2 times -// take a look at js/dev/responsiveImages.js -// - -@include retinaSupport() { - -} - - - - - - - - -// FORMS ----------------------------------------------------------------------------- -// styling of input elements is not crossbrowser -// needs additional platform tests -// http://s3.amazonaws.com/37assets/svn/480-custom_forms.html -/* -button, input, select, textarea { - line-height: normal; - font-family: inherit; - font-size: 1.6em; - padding: 5px; - margin: 0; - - border: 1px solid #555; - background: #FFF; - background: -webkit-gradient(linear, left top, left bottom, from(#FFF), to(#CCC)); - - -webkit-appearance: none; - -webkit-box-shadow: 1px 1px 1px #FFF; - - -webkit-border-radius: .5em; - -moz-border-radius: .5em; - border-radius: .5em; -} -input:focus, -select:focus, -textarea:focus { - outline: none; - border: 2px solid #F00; - margin: -1px; -} -textarea { - height: 100px; -} -input[type=checkbox], -input[type=radio] { - width: .9em; - height: .9em; - vertical-align: middle; - -webkit-border-radius: .25em; - } - input[type=radio] { - -webkit-border-radius: 2em; -} -// change color of placeholders -::-webkit-input-placeholder { - color: #F00; -} -:-moz-placeholder { - color: #F00; -} -:-ms-input-placeholder { - color: #F00; -} -*/ \ No newline at end of file diff --git a/css/styles-non-mobile-first.css b/css/styles-non-mobile-first.css deleted file mode 100644 index 31e376a..0000000 --- a/css/styles-non-mobile-first.css +++ /dev/null @@ -1 +0,0 @@ -@charset "utf-8";html,body,div,span,object,iframe,canvas,h1,h2,h3,h4,h5,h6,p,a,img,strong,sub,sup,b,u,i,center,ol,ul,li,form,label,table,tr,td,audio,video{margin:0;padding:0;border:0;outline:none;font-family:inherit;font-size:100%;vertical-align:baseline;-webkit-text-stroke:1px transparent;-webkit-font-smoothing:antialiased;-moz-font-smoothing:antialiased;-o-font-smoothing:antialiased;font-smoothing:antialiased;image-rendering:auto;-ms-interpolation-mode:bicubic;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-touch-action:none}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.clear:before,.clear:after{content:"";display:table}.clear:after{clear:both}.clear{*zoom:1}html{line-height:1;height:100%}body{font-weight:normal;font-style:normal;height:100%}ul,ol{list-style:none}table{border-collapse:collapse;border-spacing:0}a img{border:0}@font-face{font-family:"{{__My awesome font name__}}";src:url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.eot');src:url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.eot?#iefix') format('eot'),url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.woff') format('woff'), url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.ttf') format('truetype'), url('../fonts/{{__my-awesome-font-name-(file-name-without-extension)__}}.svg#webfont') format('svg');font-weight:"normal";font-style:"normal"}.trim{position:relative;white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis}.line-clamp{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.break-word{-ms-word-break:break-all;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto}.quotes:before{content:"\201C"}.quotes:after{content:"\201D"}.emphasize:first-letter{font-size:180%;font-weight:bold}.embedded-content{height:0;position:relative;padding-bottom:56.4%;overflow:hidden}.embedded-content iframe,.embedded-content object,.embedded-content embed{width:100%;height:100%;position:absolute;top:0;left:0}.no-popup{-webkit-touch-callout:none}.non-selectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.CSS3Animation{-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-moz-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-ms-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-o-transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);transition:all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1);-webkit-backface-visibility:hidden;-webkit-perspective:1000}.CSS3HardwareAcceleration{-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}body{font-family:Helvetica, Arial, Verdana, sans-serif;font-size:16px;min-width:980px}h1{font-size:2.2em;line-height:1.5em}h2{font-size:1.8em;line-height:1.5em}h3{font-size:1.4em;line-height:1.5em}p{font-size:1em;line-height:1.5em}a{text-decoration:underline}hr{height:1px;margin:1.5em 0;padding:0;border:0;border-top:1px solid #CCC;display:block}.smaller{font-size:70%} diff --git a/css/styles-raw.css b/css/styles-raw.css deleted file mode 100644 index c8e0d00..0000000 --- a/css/styles-raw.css +++ /dev/null @@ -1,470 +0,0 @@ -/* -// CSS RESET ------------------------------------------------------------------------- -// -// Based on HTML5 Boilerplate and Compass CSS Reset -// https://github.com/h5bp/html5-boilerplate -// http://compass-style.org/reference/compass/reset -*/ - -html, body, div, span, object, iframe, canvas, -h1, h2, h3, h4, h5, h6, p, a, img, -strong, sub, sup, b, u, i, center, -ol, ul, li, -form, label, table, tr, td, -audio, video { - margin: 0; - padding: 0; - border: 0; - outline: none; - font-family: inherit; - font-size: 100%; - vertical-align: baseline; - - /* Enable smooth fonts */ - -webkit-text-stroke: 1px transparent; - -webkit-font-smoothing: antialiased; - -moz-font-smoothing: antialiased; - -o-font-smoothing: antialiased; - font-smoothing: antialiased; - - /* - // Improve image scaling - // https://developer.mozilla.org/nl/docs/CSS/image-rendering - */ - image-rendering: auto; - -ms-interpolation-mode: bicubic; - - /* - // Override the semitransparent color overlay when a user clicks something - // to disable it set value to 'transparent' or 'rgba(0,0,0,0)' - */ - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - - /* - // Prevent iOS text size adjust on focus or after orientation change - // without disabling zoom with the viewport meta-tag - // https://developer.mozilla.org/en-US/docs/CSS/text-size-adjust - */ - -webkit-text-size-adjust: 100%; - -moz-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - - /* - // Enable javascript pointer events on IE Mobile by disabling events in CSS - // http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx - */ - -ms-touch-action: none; -} - -/* -// FIX BROKEN BOX-MODEL -// Note: doesn't work in IE7 (padding is still added to the box width/height) -// https://developer.mozilla.org/en-US/docs/CSS/box-sizing -*/ -*, *:before, *:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -/* -// CLEARFIX -// Note: still supports IE7 -// http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php -*/ -.clear:before, .clear:after { - content: ""; - display: table; -} -.clear:after { - clear: both; -} -.clear { - *zoom: 1; -} - - - - - - - - -/* -// BASE 64 ENCODED IMAGES -// Note: Encoded images must be smaller then 32kb (or IE won't show them) -// http://www.askapache.com/online-tools/base64-image-converter -// background: url(data:image/__typegoeshere__;base64,____); -*/ - - -/* -// USING REM-UNITS vs EM-UNITS -// Not integrating this for the moment, but it's something to keep in mind -// rem-units are supported by all major browsers (except IE7, IE8) -// http://drublic.de/blog/rem-fallback-sass-less -// http://caniuse.com/#search=rem -*/ - - -/* -// CUSTOM WEBFONTS ------------------------------------------------------------------- -// -// A custom webfont needs 4 file-types: .woff, .ttf, .svg, .eot -// all files need to be stored in ../fonts/ -// http://www.fontsquirrel.com/tools/webfont-generator -*/ - -@font-face { - font-family: "{{__My awesome font name__}}"; - src: url('../fonts/{{__some-other-font-name__}}.eot'); - src: url('../fonts/{{__some-other-font-name__}}.eot?#iefix') format('eot'), - url('../fonts/{{__some-other-font-name__}}.woff') format('woff'), - url('../fonts/{{__some-other-font-name__}}.ttf') format('truetype'), - url('../fonts/{{__some-other-font-name__}}.svg#webfont') format('svg'); - font-weight: "normal"; - font-style: "normal"; -} - - - - - - - - -/* -// HELPERS --------------------------------------------------------------------------- -*/ - -/* -// TRIM TEXT -// Trims & add ellipsis (...) -// Note: only works with a fixed width & single line text -// http://www.electrictoolbox.com/ellipsis-html-css -*/ -.trim { - position: relative; - white-space: nowrap; - overflow: hidden; - -o-text-overflow: ellipsis; - text-overflow: ellipsis; -} - -/* -// TRIM MULTILINE TEXT -// Trims & add ellipsis (...) to multiline text -// Note: only works in Webkit browsers & Safari -// http://www.css-101.org/articles/line-clamp/line-clamp_for_non_webkit-based_browsers.php -*/ -.line-clamp { - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-box-orient: vertical; - - /* number of lines to show */ - -webkit-line-clamp: 3; -} - -/* -// BREAK WORDS -// Prevent longwordsorurlswithoutspacesfrombreaking your layout -// http://blog.kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css -*/ -.break-word { - -ms-word-break: break-all; - word-break: break-all; - word-break: break-word; - -webkit-hyphens: auto; - -moz-hyphens: auto; - hyphens: auto; -} - -/* -// QUOTES -// Adds "quotes" to text -// http://www.cssbakery.com/2010/12/html-blockquote-element-css-content-and.html -*/ -.quotes:before { - content: "\201C"; -} -.quotes:after { - content: "\201D"; -} - -/* -// EMPHASIZE -// Bigger, bold first character -// Note: doesn't work on inline elements (eg ) -// http://css-tricks.com/almanac/selectors/f/first-letter/ -*/ -.emphasize:first-letter { - font-size: 180%; - font-weight: bold; -} - -/* -// EMBEDDED CONTENT -// Wrapper for fluid embedded content (vimeo, youtube, slideshare, ...) @16:9 ratio -// For this to work, use the following HTML-structure: -//
-// Embedded code... -//
-*/ -.embedded-content { - height: 0; - position: relative; - padding-bottom: 56.4%; /* 16:9 ratio = 56.25%, but 56.4% works better with vimeo */ - overflow: hidden; -} -.embedded-content iframe, -.embedded-content object, -.embedded-content embed { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; -} - -/* -// NO TOUCH CALLOUT -// Prevent a popup menu on mobile devices on touch & hold -// http://davidwalsh.name/webkit-css -*/ -.no-popup { - -webkit-touch-callout: none; -} - -/* -// NON-SELECTABLE -// Prevent something from being selected with the mouse/touch -// Different implementations of this can be found online -// but we're rolling with the generated Compass code here -*/ -.non-selectable { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -/* -// CSS3 ANIMATIONS -// Example for CSS3 animations -// http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css -*/ -.CSS3Animation { - /* enable harware acceleration */ - -webkit-transform: translate3d(0, 0, 0); - -moz-transform: translate3d(0, 0, 0); - -ms-transform: translate3d(0, 0, 0); - -o-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - - /* animate */ - -webkit-transition: all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1); - -moz-transition: all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1); - -ms-transition: all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1); - -o-transition: all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1); - transition: all 300ms cubic-bezier(0.445, 0.045, 0.0355, 1); - - /* prevent flickering in animation */ - -webkit-backface-visibility: hidden; - -webkit-perspective: 1000; -} - -/* -// ENABLE HARDWARE ACCELERATION -// Kick in hardware acceleration (better performance on mobile) -// http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css -*/ -.CSS3HardwareAcceleration { - -webkit-transform: translate3d(0, 0, 0); - -moz-transform: translate3d(0, 0, 0); - -ms-transform: translate3d(0, 0, 0); - -o-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); -} - - - - - - - - -/* -// GENERAL --------------------------------------------------------------------------- -*/ - -html { - line-height: 1; - height: 100%; -} - -body { - font-family: Helvetica, Arial, Verdana, sans-serif; - font-weight: normal; - font-style: normal; - font-size: 16px; - - /* - // If the viewport meta tag is not included: use min-width for correct - // scaling on orientationchange (IOS default page-width: 980px) - */ - min-width: 980px; - height: 100%; -} - -h1 { - font-size: 2.2em; - line-height: 1.5em; -} - -h2 { - font-size: 1.8em; - line-height: 1.5em; -} - -h3 { - font-size: 1.4em; - line-height: 1.5em; -} - -p { - font-size: 1em; - line-height: 1.5em; -} - -a { - text-decoration: underline; -} - -a:hover, -a:active { - text-decoration: none; -} - -a img { - border: 0; -} - -ul, ol { - list-style: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} - -hr { - height: 1px; - margin: 1.5em 0; - padding: 0; - border: 0; - border-top: 1px solid #CCC; - display: block; -} - -.smaller { - font-size: 70%; -} - -/* -// Add .no-touch class to the HTML tag if touchEvents are not supported -// This way we can disable :hover states on touch-devices -// Note: javascript will add it for you - see js/sources/app.js -*/ -.no-touch { - -} - - - - - - -/* -// MOBILE LANDSCAPE ------------------------------------------------------------------ -*/ - -@media screen and (min-width: 480px) { - -} - - - - - - - - -/* -// TABLET PORTRAIT ------------------------------------------------------------------- -*/ - -@media screen and (min-width: 768px) { - -} - - - - - - - - -/* -// TABLET LANDSCAPE ------------------------------------------------------------------ -*/ - -@media screen and (min-width: 1024px) { - -} - - - - - - - - -/* -// DESKTOP --------------------------------------------------------------------------- -*/ - -@media screen and (min-width: 1025px) { - -} - - - - - - - - -/* -// RETINA SUPPORT FOR HDPI SCREENS --------------------------------------------------- -// -// Include hdpi images for retina screens here -// Note: if you specify a non-retina image + retina image you'll download 2 images (!) -// If you want to enable fluid/responsive images without loading assets 2 times -// take a look at js/dev/responsiveImages.js -*/ - -@media -only screen and (-webkit-min-device-pixel-ratio: 2), -only screen and (min-resolution: 192dpi) { - /* Retina optimized styles go here */ -} - - - - - - - diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..fe8a7a7 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,1083 @@ +/*global require, process, __dirname*/ + +'use strict'; + +// REQUIRES ------------------------------------------------------------------- + +var + path = require('path'), + globule = require('globule'), + http = require ('http'), + fs = require('fs'), + ncp = require('ncp').ncp, + chalk = require('chalk'), + _ = require('lodash'), + prompt = require('inquirer').prompt, + sequence = require('run-sequence'), + ProgressBar = require('progress'), + stylish = require('jshint-stylish'), + open = require('open'), + ghdownload = require('github-download'), + browserSync = require('browser-sync'), + psi = require('psi'), + gulp = require('gulp'), + plugins = require('gulp-load-plugins')({ + config: path.join(__dirname, 'package.json') + }), + flags = require('minimist')(process.argv.slice(2)) +; + +// VARS ----------------------------------------------------------------------- + +var + gitConfig = { + user: 'flovan', + repo: 'headstart-boilerplate', + ref: '1.2.1' + }, + cwd = process.cwd(), + tmpFolder = '.tmp', + assetsFolder = 'assets', + stdoutBuffer = [], + lrStarted = false, + htmlminOptions = { + removeComments: true, + collapseWhitespace: true, + collapseBooleanAttributes: true, + removeAttributeQuotes: true, + useShortDoctype: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true, + minifyJS: true, + minifyCSS: true + }, + isProduction = ( flags.production || flags.p ) || false, + isServe = ( flags.serve || flags.s ) || false, + isOpen = ( flags.open || flags.o ) || false, + isEdit = ( flags.edit || flags.e ) || false, + isVerbose = flags.verbose || false, + isTunnel = ( flags.tunnel || flags.t ) || false, + tunnelUrl = null, + isPSI = flags.psi || false, + config = null, + bar = null +; + +// LOGGING -------------------------------------------------------------------- +// + +if (!isVerbose) { + // To get a better grip on logging by either gulp-util, console.log or direct + // writing to process.stdout, a hook is applied to stdout when not running + // in --vebose mode + require('./lib/hook.js')(process.stdout).hook('write', function (msg, encoding, fd, write) { + + // Validate message + msg = validForWrite(msg); + + // If the message is not suited for output, block it + if (!msg) { + return; + } + + if (msg.length === 1) return; + + // There is no progress bar, so just write + if (_.isNull(bar)) { + write(msg); + return; + } + + // There is a progress bar, but it hasn't completed yet, so buffer + if (!bar.complete) { + stdoutBuffer.push(msg); + return; + } + + // There is a buffer, prepend a newline to the array + if(stdoutBuffer.length) { + stdoutBuffer.unshift('\n'); + } + + // Write out the buffer untill its empty + while (stdoutBuffer.length) { + write(stdoutBuffer.shift()); + } + + // Finally, just write out + write(msg); + }); + + // Map console.warn to console.log to make sure gulp-sassgraph errors + // get validated by the code above + /*console.warn = console.log; /*function () { + + var args = Array.prototype.slice.call(arguments); + console.error('passing this to console.log: ', args); + console.log.apply(console, args); + }*/ +} + +// INIT ----------------------------------------------------------------------- +// + +gulp.task('init', function (cb) { + + // Get all files in working directory + // Exclude . files (such as .DS_Store on OS X) + var cwdFiles = _.remove(fs.readdirSync(cwd), function (file) { + + return file.substring(0,1) !== '.'; + }); + + // If there are any files + if (cwdFiles.length > 0) { + + // Make sure the user knows what is about to happen + console.log(chalk.yellow.inverse('\nThe current directory is not empty!')); + prompt({ + type: 'confirm', + message: 'Initializing will empty the current directory. Continue?', + name: 'override', + default: false + }, function (answer) { + + if (answer.override) { + // Make really really sure that the user wants this + prompt({ + type: 'confirm', + message: 'Removed files are gone forever. Continue?', + name: 'overridconfirm', + default: false + }, function (answer) { + + if (answer.overridconfirm) { + // Clean up directory, then start downloading + console.log(chalk.grey('\nEmptying current directory')); + sequence('clean-tmp', 'clean-cwd', downloadBoilerplateFiles); + } + // User is unsure, quit process + else process.exit(0); + }); + } + // User is unsure, quit process + else process.exit(0); + }); + } + // No files, start downloading + else { + console.log('\n'); + downloadBoilerplateFiles(); + } + + cb(null); +}); + +// BUILD ---------------------------------------------------------------------- +// + +gulp.task('build', function (cb) { + + // Load the config.json file + console.log(chalk.grey('\nLoading config.json...')); + fs.readFile('config.json', 'utf8', function (err, data) { + + if (err) { + console.log(chalk.red('✘ Cannot find config.json. Have you initiated Headstart through `headstart init?'), err); + process.exit(0); + } + + // Try parsing the config data as JSON + try { + config = JSON.parse(data); + } catch (err) { + console.log(chalk.red('✘ The config.json file is not valid json. Aborting.'), err); + process.exit(0); + } + + // Allow customization of gulp-htmlmin through `config.json` + if (!_.isNull(config.htmlminOptions)) { + htmlminOptions = _.assign({}, htmlminOptions, config.htmlminOptions); + } + + assetsFolder = config.assetsFolder || assetsFolder; + + // Instantiate a progressbar when not in verbose mode + if (!isVerbose) { + bar = new ProgressBar(chalk.grey('Building ' + (isProduction ? 'production' : 'development') + ' version [:bar] :percent done'), { + complete: '#', + incomplete: '-', + total: 8 + }); + updateBar(); + } else { + console.log(chalk.grey('Building ' + (isProduction ? 'production' : 'development') + ' version...')); + } + + // Run build tasks + // Serve files if Headstart was run with the --serve flag + sequence( + 'clean-export', + [ + 'sass-main', + 'scripts-main', + 'images', + 'other' + ], + 'templates', + 'manifest', + 'uncss', + function () { + console.log(chalk.green((!isProduction ? '\n' : '') + '✔ Build complete')); + if(isServe) { + gulp.start('server'); + } + cb(null); + } + ); + }); +}); + +// CLEAN ---------------------------------------------------------------------- +// + +gulp.task('clean-export', function (cb) { + + // Remove export folder and files + return gulp.src([ + config.export_templates, + config.export_assets + '/' + assetsFolder + ], {read: false}) + .pipe(plugins.rimraf({force: true})) + .on('end', updateBar) + ; +}); + +gulp.task('clean-cwd', function (cb) { + + // Remove cwd files + return gulp.src(cwd + '/*', {read: false}) + .pipe(plugins.rimraf({force: true})) + ; +}); + +gulp.task('clean-tmp', function (cb) { + + // Remove temp folder + return gulp.src(tmpFolder, {read: false}) + .pipe(plugins.rimraf({force: true})) + ; +}); + +gulp.task('clean-rev', function (cb) { + + verbose(chalk.grey('Running task "clean-rev"')); + + // Clean all revision files but the latest ones + return gulp.src(config.export_assets + '/' + assetsFolder + '/**/*.*', {read: false}) + .pipe(plugins.revOutdated(1)) + .pipe(plugins.rimraf({force: true})) + ; +}); + + +// SASS ----------------------------------------------------------------------- +// + +gulp.task('sass-main', ['sass-ie'], function (cb) { + + // Flag to catch empty streams + // https://github.com/floatdrop/gulp-watch/issues/87 + var isEmptyStream = true; + + verbose(chalk.grey('Running task "sass-main"')); + + // Process the .scss files + // While serving, this task opens a continuous watch + return gulp.src([ + assetsFolder + '/sass/*.{scss, sass, css}', + '!' + assetsFolder + '/sass/*ie.{scss, sass, css}' + ]) + .pipe(plugins.plumber()) + .pipe(plugins.rubySass({ style: (isProduction ? 'compressed' : 'nested') })) + .pipe(plugins.if(config.combineMediaQueries, plugins.combineMediaQueries())) + .pipe(plugins.autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) + .pipe(plugins.if(config.revisionCaching, plugins.rev())) + .pipe(plugins.if(isProduction, plugins.cleanCSS({ compatibility: 'ie8' }))) + .pipe(plugins.if(isProduction, plugins.rename({suffix: '.min'}))) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/css')) + .on('data', function (cb) { + + // If revisioning is on, run templates again so the refresh contains + // the newer stylesheet + if (lrStarted && config.revisionCaching) { + gulp.start('templates'); + } + + // Continue the stream + this.resume(); + }) + .on('end', updateBar) + .pipe(plugins.if(lrStarted && !config.revisionCaching, browserSync.reload({stream:true}))) + ; +}); + +gulp.task('sass-ie', function (cb) { + + // Flag to catch empty streams + // https://github.com/floatdrop/gulp-watch/issues/87 + var isEmptyStream = true; + + verbose(chalk.grey('Running task "sass-ie"')); + + // Process the .scss files + // While serving, this task opens a continuous watch + return gulp.src([ + assetsFolder + '/sass/*ie.{scss, sass, css}' + ]) + .pipe(plugins.plumber()) + .pipe(plugins.rubySass({ style: (isProduction ? 'compressed' : 'nested') })) + .pipe(plugins.rename({suffix: '.min'})) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/css')) + ; +}); + +// UNCSS ---------------------------------------------------------------------- +// +// Clean up unused CSS styles + +gulp.task('uncss', function (cb) { + + // Quit this task if not configured through config + if (!isProduction || !config.useUncss) { + updateBar(); + cb(null); + return; + } + + verbose(chalk.grey('Running task "uncss-main"')); + + // Grab all templates / partials / layout parts / etc + var templates = globule.find([config.export_templates + '/**/*.*']); + + // Grab all css files and run them through Uncss, then overwrite + // the originals with the new ones + return gulp.src(config.export_assets + '/' + assetsFolder + '/css/*.css') + .pipe(plugins.bytediff.start()) + .pipe(plugins.uncss({ + html: templates || [], + ignore: config.uncssIgnore || [] + })) + .pipe(plugins.bytediff.stop(function (data) { + updateBar(); + + data.percent = Math.round(data.percent*100); + data.savings = Math.round(data.savings/1024); + + return chalk.grey('' + data.fileName + ' is now ') + chalk.green(data.percent + '% ' + (data.savings > 0 ? 'smaller' : 'larger')) + chalk.grey(' (saved ' + data.savings + 'KB)'); + })) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/css')) + ; +}); + +// SCRIPTS -------------------------------------------------------------------- +// + +// JSHint options: http://www.jshint.com/docs/options/ +gulp.task('hint-scripts', function (cb) { + + // Quit this task if hinting isn't turned on + if (!config.hint) { + cb(null); + return; + } + + verbose(chalk.grey('Running task "hint-scripts"')); + + // Hint all non-lib js files and exclude _ prefixed files + return gulp.src([ + assetsFolder + '/js/*.js', + assetsFolder + '/js/core/*.js', + '!_*.js' + ]) + .pipe(plugins.plumber()) + .pipe(plugins.jshint('.jshintrc')) + .pipe(plugins.jshint.reporter(stylish)) + ; +}); + +gulp.task('scripts-main', ['hint-scripts', 'scripts-view', 'scripts-ie'], function () { + + var files = [ + assetsFolder + '/js/libs/jquery*.js', + assetsFolder + '/js/libs/ender*.js', + + (isProduction ? '!' : '') + assetsFolder + '/js/libs/dev/*.js', + + assetsFolder + '/js/libs/**/*.js', + // TODO: remove later + assetsFolder + '/js/core/**/*.js', + // + assetsFolder + '/js/*.js', + '!' + assetsFolder + '/js/view-*.js', + '!**/_*.js' + ]; + + verbose(chalk.grey('Running task "scripts-main"')); + + if (isProduction) { + var numFiles = globule.find(files).length; + console.log(chalk.green('✄ Concatenated ' + numFiles + ' JS files')); + } + + // Process .js files + // Files are ordered for dependency sake + return gulp.src(files, {base: '' + assetsFolder + '/js'}) + .pipe(plugins.plumber()) + .pipe(plugins.deporder()) + .pipe(plugins.if(isProduction, plugins.stripDebug())) + .pipe(plugins.if(isProduction, plugins.concat('core-libs.js'))) + .pipe(plugins.if(config.revisionCaching, plugins.rev())) + .pipe(plugins.if(isProduction, plugins.rename({extname: '.min.js'}))) + .pipe(plugins.if(isProduction, plugins.uglify())) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/js')) + .on('end', updateBar) + ; +}); + +gulp.task('scripts-view', function (cb) { + + verbose(chalk.grey('Running task "scripts-view"')); + + return gulp.src(assetsFolder + '/js/view-*.js') + .pipe(plugins.plumber()) + .pipe(plugins.if(config.revisionCaching, plugins.rev())) + .pipe(plugins.if(isProduction, plugins.rename({suffix: '.min'}))) + .pipe(plugins.if(isProduction, plugins.stripDebug())) + .pipe(plugins.if(isProduction, plugins.uglify())) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/js')) + ; +}); + +gulp.task('scripts-ie', function (cb) { + + verbose(chalk.grey('Running task "scripts-ie"')); + + // Process .js files + // Files are ordered for dependency sake + gulp.src([ + assetsFolder + '/js/ie/head/**/*.js', + '!**/_*.js' + ]) + .pipe(plugins.plumber()) + .pipe(plugins.deporder()) + .pipe(plugins.concat('ie-head.js')) + .pipe(plugins.if(isProduction, plugins.stripDebug())) + .pipe(plugins.rename({extname: '.min.js'})) + .pipe(plugins.uglify()) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/js')); + + gulp.src([ + assetsFolder + '/js/ie/body/**/*.js', + '!**/_*.js' + ]) + .pipe(plugins.plumber()) + .pipe(plugins.deporder()) + .pipe(plugins.concat('ie-body.js')) + .pipe(plugins.if(isProduction, plugins.stripDebug())) + .pipe(plugins.rename({extname: '.min.js'})) + .pipe(plugins.uglify()) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/js')); + + cb(null); +}); + +// IMAGES --------------------------------------------------------------------- +// + +gulp.task('images', function (cb) { + + verbose(chalk.grey('Running task "images"')); + + // Make a copy of the favicon.png, and make a .ico version for IE + // Move to root of export folder + gulp.src(assetsFolder + '/images/icons/favicon.png') + .pipe(plugins.rename({extname: '.ico'})) + //.pipe(plugins.if(config.revisionCaching, plugins.rev())) + .pipe(gulp.dest(config.export_misc)) + ; + + // Grab all image files, filter out the new ones and copy over + // In --production mode, optimize them first + return gulp.src([ + assetsFolder + '/images/**/*', + '!_*' + ]) + .pipe(plugins.plumber()) + .pipe(plugins.newer(config.export_assets + '/' + assetsFolder + '/images')) + .pipe(plugins.if(isProduction, plugins.imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))) + //.pipe(plugins.if(config.revisionCaching, plugins.rev())) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder + '/images')) + .pipe(plugins.if(lrStarted, browserSync.reload({stream:true}))) + ; +}); + +// OTHER ---------------------------------------------------------------------- +// + +gulp.task('other', ['misc'], function (cb) { + + verbose(chalk.grey('Running task "other"')); + + // Make sure other files and folders are copied over + // eg. fonts, videos, ... + return gulp.src([ + assetsFolder + '/**/*', + '!' + assetsFolder + '/sass', + '!' + assetsFolder + '/sass/**/*', + '!' + assetsFolder + '/js/**/*', + '!' + assetsFolder + '/images/**/*', + '!_*' + ]) + .pipe(plugins.plumber()) + //.pipe(plugins.if(config.revisionCaching, plugins.rev())) + .pipe(gulp.dest(config.export_assets + '/' + assetsFolder)) + .on('end', updateBar) + ; +}); + +// MISC ----------------------------------------------------------------------- +// + +gulp.task('misc', function (cb) { + + // In --production mode, copy over all the other stuff + if (isProduction) { + verbose(chalk.grey('Running task "misc"')); + + // Make a functional version of the htaccess.txt + gulp.src('misc/htaccess.txt') + .pipe(plugins.rename('.htaccess')) + .pipe(gulp.dest(config.export_misc)) + ; + + gulp.src(['misc/*', '!misc/htaccess.txt', '!_*']) + .pipe(gulp.dest(config.export_misc)) + ; + } + + cb(null); +}); + +// TEMPLATES ------------------------------------------------------------------ +// + +gulp.task('templates', ['clean-rev'], function (cb) { + + verbose(chalk.grey('Running task "templates"')); + + // If assebly is off, export all folders and files + if (!config.assemble_templates) { + gulp.src(['templates/**/*', '!templates/*.*', '!_*']) + .pipe(gulp.dest(config.export_templates)); + } + + // Find number of "root" templates to parse and keep count + var numTemplates = globule.find(['templates/*.*', '!_*']).length, + count = 0, + unvalidatedFiles = []; + + // Go over all root template files + gulp.src(['templates/*.*', '!_*']) + .pipe(plugins.tap(function (htmlFile) { + + var + // Extract bits from filename + baseName = path.basename(htmlFile.path), + nameParts = baseName.split('.'), + ext = _.without(nameParts, _.first(nameParts)).join('.'), + viewBaseName = _.last(nameParts[0].split('view-')), + // Make sure Windows paths work down below + cwdParts = cwd.replace(/\\/g, '/').split('/'), + + // Make a collection of file globs + // Production will get 1 file only + // Development gets raw base files + injectItems = isProduction ? + [ + config.export_assets + '/' + assetsFolder + '/js/core-libs*.min.js', + config.export_assets + '/' + assetsFolder + '/js/view-' + viewBaseName + '*.min.js' + ] + : + [ + config.export_assets + '/' + assetsFolder + '/js/libs/jquery*.js', + config.export_assets + '/' + assetsFolder + '/js/libs/ender*.js', + + (isProduction ? '!' : '') + config.export_assets + '/' + assetsFolder + '/js/libs/dev/*.js', + + config.export_assets + '/' + assetsFolder + '/js/libs/*.js', + config.export_assets + '/' + assetsFolder + '/js/core/*.js', + config.export_assets + '/' + assetsFolder + '/js/**/*.js', + + '!' + config.export_assets + '/' + assetsFolder + '/**/_*.js', + '!' + config.export_assets + '/' + assetsFolder + '/js/ie*.js' + ] + ; + + // Include the css + injectItems.push(config.export_assets + '/' + assetsFolder + '/css/main*.css'); + injectItems.push(config.export_assets + '/' + assetsFolder + '/css/view-' + viewBaseName + '*.css'); + + // Put items in a stream and order dependencies + injectItems = gulp.src(injectItems) + .pipe(plugins.plumber()) + .pipe(plugins.ignore.include(function (file) { + + var fileBase = path.basename(file.path); + + // Exclude filenames with "view-" not matching the current view + if (fileBase.indexOf('view-') > -1 && fileBase.indexOf('.js') > -1 && fileBase.indexOf(viewBaseName) < 0) { + return false; + } + + // Pass through all the other files + return true; + })) + .pipe(plugins.deporder(baseName)); + + // On the current template + gulp.src('templates/' + baseName) + .pipe(plugins.plumber()) + // Piping plugins.newer() blocks refreshes on partials and layout parts :( + //.pipe(plugins.newer(config.export_templates + '/' + baseName)) + .pipe(plugins.if(config.assemble_templates, plugins.compileHandlebars({ + templateName: baseName + }, { + batch: ['templates/layout', 'templates/partials'], + helpers: { + equal: function (v1, v2, options) { + return (v1 == v2) ? options.fn(this) : options.inverse(this); + } + } + }))) + .pipe(plugins.inject(injectItems, { + ignorePath: [ + _.without(cwdParts, cwdParts.splice(-1)[0]).join('/') + ].concat(config.export_assets.split('/')), + addRootSlash: false, + addPrefix: config.template_asset_prefix || '' + })) + .pipe(plugins.if(config.w3c && ext === 'html', plugins.w3cjs({ + doctype: 'HTML5', + charset: 'utf-8' + }))) + .pipe(plugins.if(config.minifyHTML, plugins.htmlmin(htmlminOptions))) + .pipe(gulp.dest(config.export_templates)) + .on('end', function () { + // Since above changes are made in a tapped stream + // We have to count to make sure everything is parsed + count = count + 1; + if (count == numTemplates) { + // Reload when serving + if (lrStarted) { + browserSync.reload(/*{stream:true}*/); + } + + // Update the loadbar + updateBar(); + + // Report unvalidated files + if (unvalidatedFiles.length) { + console.log(chalk.yellow('✘ Couldn\'t validate: ' + unvalidatedFiles.join(', '))); + console.log(chalk.yellow.inverse('W3C validation only works for HTML files')); + } + + // Report the end of this task + cb(null); + } + }) + ; + + if (config.w3c && ext !== 'html') { + unvalidatedFiles.push(baseName); + } + })) + ; +}); + +// MANIFEST ------------------------------------------------------------------- +// + +gulp.task('manifest', function (cb) { + + // Quit this task if the revisions aren't turned on + if (!config.revisionCaching) { + updateBar(); + cb(null); + return; + } + + verbose(chalk.grey('Running task "manifest"')); + + return gulp.src([ + config.export_assets + '/' + assetsFolder + '/js/*', + config.export_assets + '/' + assetsFolder + '/css/*' + ]) + .pipe(plugins.manifest({ + filename: 'app.manifest', + exclude: 'app.manifest' + })) + .pipe(gulp.dest(config.export_misc)) + .on('end', updateBar) + ; +}); + +// SERVER --------------------------------------------------------------------- +// + +gulp.task('server', ['browsersync'], function (cb) { + + verbose(chalk.grey('Running task "server"')); + console.log(chalk.grey('Watching files...')); + + gulp.watch([assetsFolder + '/sass/**/*.{scss, sass, css}', '!' + assetsFolder + '/sass/*ie.{scss, sass, css}'], ['sass-main']).on('change', watchHandler); + gulp.watch([assetsFolder + '/js/**/view-*.js'], ['scripts-view', 'templates']).on('change', watchHandler); + gulp.watch([assetsFolder + '/js/**/*.js', '!**/view-*.js'], ['scripts-main', 'templates']).on('change', watchHandler); + gulp.watch([assetsFolder + '/images/**/*'], ['images']).on('change', watchHandler); + gulp.watch(['templates/**/*'], ['templates']).on('change', watchHandler); + + cb(null); +}); + +gulp.task('browsersync', function (cb) { + + verbose(chalk.grey('Running task "browsersync"')); + console.log(chalk.grey('Launching server...')); + + // Grab the event emitter and add some listeners + var evt = browserSync.emitter; + evt.on('init', bsInitHandler); + evt.on('service:running', bsRunningHandler); + + // Serve files and connect browsers + browserSync.init(null, { + server: _.isUndefined(config.proxy) ? { + baseDir: config.export_templates + } : false, + logConnections: false, + logLevel: 'silent', // 'debug' + browser: config.browser || 'default', + open: isOpen, + port: config.port || 3000, + proxy: config.proxy || false, + tunnel: isTunnel || null + }, function (err, data) { + + // Use this callback to catch errors, which aren't transmitted + // through `init` + if (err !== null) { + console.log( + chalk.red('✘ Setting up a local server failed... Please try again. Aborting.\n') + + chalk.red(err) + ); + process.exit(0); + } + + cb(null); + }); +}); + +// PAGESPEED INSIGHTS --------------------------------------------------------- +// + +gulp.task('psi', function (cb) { + + // Quit this task if no flag was set + if(!isPSI) { + cb(null); + return; + } + + verbose(chalk.grey('Running task "psi"')); + console.log(chalk.grey('Running PageSpeed Insights (might take a while)...')); + + // Define PSI options + var opts = { + url: tunnelUrl, + strategy: flags.strategy || "desktop", + threshold: 80 + }; + + // Set the key if one was passed in + if (!!flags.key && _.isString(flags.key)) { + console.log(chalk.yellow.inverse('Using a key is not yet supported as it just crashes the process. For now, continue using `--psi` without a key.')); + // TODO: Fix key + //opts.key = flags.key; + } + + // Run PSI + psi(opts, function (err, data) { + + // If there was an error, log it and exit + if (err !== null) { + console.log(chalk.red('✘ Threshold of ' + opts.threshold + ' not met with score of ' + data.score)); + } else { + console.log(chalk.green('✔ Threshold of ' + opts.threshold + ' exceeded with score of ' + data.score)); + } + + cb(null); + }); +}); + +// HELPER FUNCTIONS ----------------------------------------------------------- +// + +// Download the boilerplate files +function downloadBoilerplateFiles () { + + console.log(chalk.grey('Downloading boilerplate files...')); + + // If a custom repo was passed in, use it + if (!!flags.base) { + + // Check if there's a slash + if (flags.base.indexOf('/') < 0) { + console.log(chalk.red('✘ Please pass in a correct repository, eg. `username/repository` or `user/repo#branch. Aborting.\n')); + process.exit(0); + } + + // Check if there's a reference + if (flags.base.indexOf('#') > -1) { + flags.base = flags.base.split('#'); + gitConfig.ref = flags.base[1]; + flags.base = flags.base[0]; + } else { + gitConfig.ref = null; + } + + // Extract username and repo + flags.base = flags.base.split('/'); + gitConfig.user = flags.base[0]; + gitConfig.repo = flags.base[1]; + + // Extra validation + if (gitConfig.user.length <= 0) { + console.log(chalk.red('✘ The passed in username is invald. Aborting.\n')); + process.exit(0); + } + if (gitConfig.repo.length <= 0) { + console.log(chalk.red('✘ The passed in repository is invald. Aborting.\n')); + process.exit(0); + } + } + + // Download the boilerplate files to a temp folder + // This is to prevent a ENOEMPTY error + ghdownload(gitConfig, tmpFolder) + // Let the user know when something went wrong + .on('error', function (error) { + console.log(chalk.red('✘ An error occurred. Aborting.'), error); + process.exit(0); + }) + // Download succeeded + .on('end', function () { + console.log( + chalk.green('✔ Download complete!\n') + + chalk.grey('Cleaning up...') + ); + + // Move to working directory, clean temp, finish init + ncp(tmpFolder, cwd, function (err) { + + if (err) { + console.log(chalk.red('✘ Something went wrong. Please try again'), err); + process.exit(0); + } + + sequence('clean-tmp', function () { + finishInit(); + }); + }); + }) + // TODO: Try to catch the error when a ZIP has "NOEND" + ; +} + +// Wrap up after running init and +// downloading the boilerplate files +function finishInit () { + + // Ask the user if he wants to continue and + // have the files served and opened + prompt({ + type: 'confirm', + message: 'Would you like to have these files served?', + name: 'build', + default: true + }, function (buildAnswer) { + + if (buildAnswer.build) { + isServe = true; + prompt({ + type: 'confirm', + message: 'Should they be opened in the browser?', + name: 'open', + default: true + + }, function (openAnswer) { + + if (openAnswer.open) isOpen = true; + prompt({ + type: 'confirm', + message: 'Should they be opened in an editor?', + name: 'edit', + default: true + + }, function (editAnswer) { + + if (editAnswer.edit) isEdit = true; + gulp.start('build'); + }); + }); + } + else process.exit(0); + }); +} + +// Update the loadbar if one is set +function updateBar () { + if (!isVerbose && bar !== null) { + bar.tick(); + } +} + +// Handle change events for Gulp watch instances +function watchHandler (e) { + console.log(chalk.grey('"' + e.path.split('/').pop() + '" was ' + e.type)); +} + +// Browser Sync `init` event handler +function bsInitHandler (data) { + + // Store started state globally + lrStarted = true; + + // Show some logs + console.log(chalk.cyan('🌐 Local access at'), chalk.magenta(data.options.urls.local)); + console.log(chalk.cyan('🌐 Network access at'), chalk.magenta(data.options.urls.external)); + + if (isOpen) { + console.log( + chalk.cyan('☞ Opening in'), + chalk.magenta(config.browser) + ); + } + + // Open an editor if needed + if (isEdit) { + openEditor(); + } +} + +// Browser Sync `service:running event handler +function bsRunningHandler (data) { + + if (data.tunnel) { + tunnelUrl = data.tunnel; + console.log(chalk.cyan('🌐 Public access at'), chalk.magenta(tunnelUrl)); + + if (isPSI) { + gulp.start('psi'); + } + } else if (isPSI) { + console.log(chalk.red('✘ Running PSI cannot be started without a tunnel. Please restart Headstart with the `--tunnel` or `t` flag.')); + } +} + +// Open files in editor +function openEditor () { + + console.log( + chalk.cyan('☞ Editing in'), + chalk.magenta(config.editor) + ); + open(cwd, config.editor); +} + +// Make extra logs in verbose mode +function verbose (msg) { + + if(isVerbose) console.log(msg); +} + +// Check if the passed in string may be logged out +function validForWrite (msg, cleanMsg) { + + cleanMsg = chalk.stripColor(msg); + + // Detect gulp-util "[XX:XX:XX] ..." logs, + if (/^\[[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\]/.test(cleanMsg)) { + var allowFlag = false; + + // Allow gulp-ruby-sass errors, + // but format them a bit + if (cleanMsg.indexOf('was changed') > -1) { + msg = cleanMsg.split(' '); + msg.shift(); + msg[0] = msg[0].split('/').pop(); + msg = msg.join(' ').trim(); + msg = chalk.grey(msg) + '\n'; + + allowFlag = true; + } + + // Allow gulp-plumber errors, + // but format them a bit + if (!allowFlag && cleanMsg.indexOf('Plumber found') > - 1) { + msg = cleanMsg.split('Plumber found unhandled error:').pop().trim(); + msg = chalk.red.inverse('ERROR') + ' ' + msg + '\n'; + + allowFlag = true; + } + + // Grab the result of gulp-imagemin + if (!allowFlag && cleanMsg.indexOf('gulp-imagemin: Minified') > -1) { + msg = cleanMsg.split('gulp-imagemin:').pop().trim(); + msg = chalk.green('✄ ' + msg) + '\n'; + + allowFlag = true; + } + + // Allow W3C validation errors, + // but format them a bit + if (!allowFlag && cleanMsg.indexOf('HTML Error:') > -1) { + msg = cleanMsg.split('HTML Error:').pop().trim(); + msg = chalk.red.inverse('HTML ERROR') + ' ' + msg + '\n'; + + allowFlag = true; + } + + // Grab the result of CSSMin + if (!allowFlag && cleanMsg.indexOf('.css is now') > -1) { + msg = cleanMsg.split(' ').slice(1).join(' ').trim(); + msg = chalk.green('✄ ' + msg) + '\n'; + + allowFlag = true; + } + + // Block all the others + if (!allowFlag) { + return false; + } + } + + // Block sass-graph errors + var graphMatches = _.filter(['failed to resolve', 'failed to add'], function (part) { + return cleanMsg.indexOf(part) > -1; + }); + if (/^failed to resolve|failed to add/.test(msg)) { + return false; + } + + return msg; +} diff --git a/icons/114x114.png b/icons/114x114.png deleted file mode 100644 index 87990fa..0000000 Binary files a/icons/114x114.png and /dev/null differ diff --git a/icons/144x144.png b/icons/144x144.png deleted file mode 100644 index e148917..0000000 Binary files a/icons/144x144.png and /dev/null differ diff --git a/icons/200x200.jpg b/icons/200x200.jpg deleted file mode 100644 index b802317..0000000 Binary files a/icons/200x200.jpg and /dev/null differ diff --git a/icons/32x32.png b/icons/32x32.png deleted file mode 100644 index 4e0af6b..0000000 Binary files a/icons/32x32.png and /dev/null differ diff --git a/icons/450x300.jpg b/icons/450x300.jpg deleted file mode 100644 index 5a3874b..0000000 Binary files a/icons/450x300.jpg and /dev/null differ diff --git a/icons/57x57.png b/icons/57x57.png deleted file mode 100644 index 212b0d7..0000000 Binary files a/icons/57x57.png and /dev/null differ diff --git a/icons/72x72.png b/icons/72x72.png deleted file mode 100644 index 6a430a3..0000000 Binary files a/icons/72x72.png and /dev/null differ diff --git a/icons/favicon.ico b/icons/favicon.ico deleted file mode 100644 index cab46cd..0000000 Binary files a/icons/favicon.ico and /dev/null differ diff --git a/index.html b/index.html deleted file mode 100644 index 89ffc5d..0000000 --- a/index.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - - - - - - - - - - - - Boilerplate 0.2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/js/app-default.min.js b/js/app-default.min.js deleted file mode 100644 index a821779..0000000 --- a/js/app-default.min.js +++ /dev/null @@ -1 +0,0 @@ -var Utils=Utils||(Utils={});Utils.client={init:function(){this.isIE=!("__proto__"in{});this.isTouch="ontouchstart"in document||!1;this.isPhone=this.isTouch&&window.innerWidth<768;this.isTablet=this.isTouch&&!this.isPhone;this.isStandalone=navigator.standalone||!1;this.hasCSSTransition=this.checkSupport("Transition");this.hasCSSTransform=this.checkSupport("Transform");this.hasCSSBackgroundSize=this.checkSupport("backgroundSize");this.hasCSSLineClamp=this.checkSupport("webkitLineClamp")},checkSupport:function(e){var t=["webkit","Moz","O","ms",""],n=t.length;while(n--)if(t[n]+e in document.body.style)return!0;return!1}};Utils.client.init();(function(){var e=0,t=["ms","moz","webkit","o"];for(var n=0;nt){n=s;e.apply(r,i)}}};Utils.onWindowResize=function(e){function r(){var t=document.documentElement.clientWidth,n=document.documentElement.clientHeight;e(t,n)}var t=typeof _=="function"?_.debounce:Utils.debounce?Utils.debounce:null,n=75;t||console.log("ALERT: Can't find _.debounce or Utils.debounce (__utils.events.resize.js)");window.attachEvent&&window.attachEvent("onresize",t(r,n));window.addEventListener&&window.addEventListener("resize",t(r,n),!1);window.orientationchange&&window.addEventListener("orientationchange",t(r,n),!1);r()};Utils.trimString=function(e,t){if(e.length>t){e=e.substring(0,t);e+="..."}return e};Utils.capitalizeString=function(e,t){return t&&t==="each-word"?e.replace(/(?:^|\s)\S/g,function(e){return e.toUpperCase()}):t&&t==="all-chars"?e.toUpperCase():e.charAt(0).toUpperCase()+e.substr(1).toLowerCase()};$(document).ready(function(){Utils.client.isTouch||(document.documentElement.className="no-touch");Utils.onWindowResize(function(e,t){})}); \ No newline at end of file diff --git a/js/app-require.min.js b/js/app-require.min.js deleted file mode 100644 index a030799..0000000 --- a/js/app-require.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(){var e=0,t=["ms","moz","webkit","o"];for(var n=0;nt){n=s;e.apply(r,i)}}};Utils.onWindowResize=function(e){function r(){var t=document.documentElement.clientWidth,n=document.documentElement.clientHeight;e(t,n)}var t=typeof _=="function"?_.debounce:Utils.debounce?Utils.debounce:null,n=75;t||console.log("ALERT: Can't find _.debounce or Utils.debounce (__utils.events.resize.js)");window.attachEvent&&window.attachEvent("onresize",t(r,n));window.addEventListener&&window.addEventListener("resize",t(r,n),!1);window.orientationchange&&window.addEventListener("orientationchange",t(r,n),!1);r()};Utils.trimString=function(e,t){if(e.length>t){e=e.substring(0,t);e+="..."}return e};Utils.capitalizeString=function(e,t){return t&&t==="each-word"?e.replace(/(?:^|\s)\S/g,function(e){return e.toUpperCase()}):t&&t==="all-chars"?e.toUpperCase():e.charAt(0).toUpperCase()+e.substr(1).toLowerCase()};define(["dom","underscore","backbone"],function(e,t,n){Utils.client.isTouch||(document.documentElement.className="no-touch");Utils.onWindowResize(function(e,t){})}); \ No newline at end of file diff --git a/js/config-require.min.js b/js/config-require.min.js deleted file mode 100644 index 71904b9..0000000 --- a/js/config-require.min.js +++ /dev/null @@ -1 +0,0 @@ -var Utils=Utils||(Utils={});Utils.client={init:function(){this.isIE=!("__proto__"in{});this.isTouch="ontouchstart"in document||!1;this.isPhone=this.isTouch&&window.innerWidth<768;this.isTablet=this.isTouch&&!this.isPhone;this.isStandalone=navigator.standalone||!1;this.hasCSSTransition=this.checkSupport("Transition");this.hasCSSTransform=this.checkSupport("Transform");this.hasCSSBackgroundSize=this.checkSupport("backgroundSize");this.hasCSSLineClamp=this.checkSupport("webkitLineClamp")},checkSupport:function(e){var t=["webkit","Moz","O","ms",""],n=t.length;while(n--)if(t[n]+e in document.body.style)return!0;return!1}};Utils.client.init();require.config({deps:["app-require.min"],paths:{dom:Utils.client.isIE?["//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min","libs/jquery-1.10.0.min"]:["//cdnjs.cloudflare.com/ajax/libs/zepto/1.0/zepto.min","libs/zepto.min"],json2:["//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2","libs/json2.min"],underscore:["//cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min","libs/lodash-1.2.1.min"],backbone:["//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min","libs/backbone-1.0.0.min"]},shim:{dom:{exports:Utils.client.ieIE?"jQuery":"Zepto"},backbone:{deps:["json2","underscore","dom"],exports:"Backbone"},underscore:{exports:"_"}}}); \ No newline at end of file diff --git a/js/libs/backbone-1.0.0.min.js b/js/libs/backbone-1.0.0.min.js deleted file mode 100644 index 3541019..0000000 --- a/js/libs/backbone-1.0.0.min.js +++ /dev/null @@ -1,4 +0,0 @@ -(function(){var t=this;var e=t.Backbone;var i=[];var r=i.push;var s=i.slice;var n=i.splice;var a;if(typeof exports!=="undefined"){a=exports}else{a=t.Backbone={}}a.VERSION="1.0.0";var h=t._;if(!h&&typeof require!=="undefined")h=require("underscore");a.$=t.jQuery||t.Zepto||t.ender||t.$;a.noConflict=function(){t.Backbone=e;return this};a.emulateHTTP=false;a.emulateJSON=false;var o=a.Events={on:function(t,e,i){if(!l(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,i){if(!l(this,"once",t,[e,i])||!e)return this;var r=this;var s=h.once(function(){r.off(t,s);e.apply(this,arguments)});s._callback=e;return this.on(t,s,i)},off:function(t,e,i){var r,s,n,a,o,u,c,f;if(!this._events||!l(this,"off",t,[e,i]))return this;if(!t&&!e&&!i){this._events={};return this}a=t?[t]:h.keys(this._events);for(o=0,u=a.length;o").attr(t);this.setElement(e,false)}else{this.setElement(h.result(this,"el"),false)}}});a.sync=function(t,e,i){var r=k[t];h.defaults(i||(i={}),{emulateHTTP:a.emulateHTTP,emulateJSON:a.emulateJSON});var s={type:r,dataType:"json"};if(!i.url){s.url=h.result(e,"url")||U()}if(i.data==null&&e&&(t==="create"||t==="update"||t==="patch")){s.contentType="application/json";s.data=JSON.stringify(i.attrs||e.toJSON(i))}if(i.emulateJSON){s.contentType="application/x-www-form-urlencoded";s.data=s.data?{model:s.data}:{}}if(i.emulateHTTP&&(r==="PUT"||r==="DELETE"||r==="PATCH")){s.type="POST";if(i.emulateJSON)s.data._method=r;var n=i.beforeSend;i.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",r);if(n)return n.apply(this,arguments)}}if(s.type!=="GET"&&!i.emulateJSON){s.processData=false}if(s.type==="PATCH"&&window.ActiveXObject&&!(window.external&&window.external.msActiveXFilteringEnabled)){s.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var o=i.xhr=a.ajax(h.extend(s,i));e.trigger("request",e,o,i);return o};var k={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};a.ajax=function(){return a.$.ajax.apply(a.$,arguments)};var S=a.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var $=/\((.*?)\)/g;var T=/(\(\?)?:\w+/g;var H=/\*\w+/g;var A=/[\-{}\[\]+?.,\\\^$|#\s]/g;h.extend(S.prototype,o,{initialize:function(){},route:function(t,e,i){if(!h.isRegExp(t))t=this._routeToRegExp(t);if(h.isFunction(e)){i=e;e=""}if(!i)i=this[e];var r=this;a.history.route(t,function(s){var n=r._extractParameters(t,s);i&&i.apply(r,n);r.trigger.apply(r,["route:"+e].concat(n));r.trigger("route",e,n);a.history.trigger("route",r,e,n)});return this},navigate:function(t,e){a.history.navigate(t,e);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=h.result(this,"routes");var t,e=h.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(A,"\\$&").replace($,"(?:$1)?").replace(T,function(t,e){return e?t:"([^/]+)"}).replace(H,"(.*?)");return new RegExp("^"+t+"$")},_extractParameters:function(t,e){var i=t.exec(e).slice(1);return h.map(i,function(t){return t?decodeURIComponent(t):null})}});var I=a.History=function(){this.handlers=[];h.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var P=/^\/+|\/+$/g;var O=/msie [\w.]+/;var C=/\/$/;I.started=false;h.extend(I.prototype,o,{interval:50,getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=this.location.pathname;var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.substr(i.length)}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(I.started)throw new Error("Backbone.history has already been started");I.started=true;this.options=h.extend({},{root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var e=this.getFragment();var i=document.documentMode;var r=O.exec(navigator.userAgent.toLowerCase())&&(!i||i<=7);this.root=("/"+this.root+"/").replace(P,"/");if(r&&this._wantsHashChange){this.iframe=a.$('