diff --git a/.gitignore b/.gitignore index 6b19995f..09ae2fa8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,13 @@ # https://help.github.com/articles/ignoring-files # Example .gitignore files: https://github.com/github/gitignore + +# Jekyll metadata _gh_pages +_site +docs/.jekyll-metadata +docs/dist + *.log .sass-cache Thumbs.db diff --git a/.travis.yml b/.travis.yml index 4a602bb2..70e8d377 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ rvm: before_script: - npm install -g grunt-cli + - npm install -g bower #- export DISPLAY=:99.0 #- sh -e /etc/init.d/xvfb start # Install meteor @@ -18,4 +19,4 @@ before_script: # Install spacejam, Meteor's CI helper #- npm install -g spacejam -script: bundle install && grunt cibuild +script: bower install && bundle install && grunt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b0af6e5..100622f1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -217,3 +217,49 @@ Run `grunt build` before committing to ensure your changes follow our coding sta By contributing your code, you agree to license your contribution under the [MIT License](LICENSE). By contributing to the documentation, you agree to license your contribution under the [Creative Commons Attribution 3.0 Unported License](docs/LICENSE). + +## Building documentation + +1. Checkout the master branch from the project root directory + + ```bash + $ git checkout master + ``` + +1. Bundle install (if not already done) + ```bash + $ bundle install + ``` + +1. Checkout the `gh-pages` branch in `_gh_pages` directory + + ```bash + $ git clone git@github.com:FezVrasta/bootstrap-material-design.git -b gh-pages _gh_pages + ``` + + **rosskevin only note** when ready kill all files and commit a clean gh-pages directory for a clean start. + + The `_gh_pages` directory is already in `.gitignore` so we are just fine. + +1. Copy the latest code to the `docs/dist` (if not already done) + ```bash + $ grunt docs + ``` + +1. Let's test changes to the documentation: + + ```bash + $ jekyll serve + ``` +1. Browse to [http://127.0.0.1:9001/](http://127.0.0.1:9001/) + +1. Make some changes to files in the `docs` directory and review them + +1. Commit and push the newly generated site on github: + + ```bash + $ cd _gh_pages + $ git add . + $ git commit -m "First generation" + $ git push + ``` diff --git a/Gemfile b/Gemfile index 92ee8961..a3e37be2 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,6 @@ source 'https://rubygems.org' gem 'sass' +# gem 'jekyll' +# gem 'jekyll-less' +gem 'therubyracer' diff --git a/Gruntfile.js b/Gruntfile.js index 654a3deb..cb50e92e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -3,8 +3,61 @@ module.exports = function (grunt) { require("load-grunt-tasks")(grunt); + var path = require('path'); + var configBridge = grunt.file.readJSON('./grunt/configBridge.json', {encoding: 'utf8'}); + var generateIconsData = require('./grunt/bmd-icons-data-generator.js'); + + Object.keys(configBridge.paths).forEach(function (key) { + configBridge.paths[key].forEach(function (val, i, arr) { + arr[i] = path.join('./docs/assets', val); + }); + }); + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + jqueryCheck: configBridge.config.jqueryCheck.join('\n'), + jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'), + + + // Task configuration. + clean: { + dist: 'dist', + docs: 'docs/dist' + }, + + jekyll: { + options: { + config: '_config.yml' + }, + docs: {}, + github: { + options: { + raw: 'github: true' + } + } + }, + + htmlmin: { + dist: { + options: { + collapseWhitespace: true, + conservativeCollapse: true, + minifyCSS: true, + minifyJS: true, + removeAttributeQuotes: true, + removeComments: true + }, + expand: true, + cwd: '_gh_pages', + dest: '_gh_pages', + src: [ + '**/*.html', + '!examples/**/*.html' + ] + } + }, + htmllint: { //options: { // stoponerror: false, @@ -35,13 +88,34 @@ module.exports = function (grunt) { files: [{ expand: true, cwd: "less", - src: ["*.less", "!_mixins.less", "!_mixins-fullpalette.less", "!_mixins-shared.less"], + src: ["*.less", "!_mixins.less", "!_mixins-fullpalette.less", "!_mixins-shared.less", "!_import-bs*"], ext: ".scss", dest: "sass" }], options: { replacements: [ + // convert bootstrap imports + { // https://regex101.com/r/bM6cP0/2 + pattern: /bower_components\/(bootstrap\/less\/)/gi, + replacement: "bower_components\/bootstrap-sass\/assets\/stylesheets\/bootstrap\/", + order: 2 + }, + + // convert conditional when not + { // https://regex101.com/r/cX6uF4/1 + pattern: /& when not \(isstring\(\$parent\)\)/gi, + replacement: "@if not $parent", + order: 2 + }, + + // convert conditional when + { // https://regex101.com/r/gH0jP0/2 + pattern: /& when \(isstring\(\$parent\)\)/gi, + replacement: "@else", + order: 2 + }, + // convert all shadow mixins { // https://regex101.com/r/sJ2lH4/1 pattern: /.shadow-z-(\d+)((?:-hover)?) {/gi, @@ -205,6 +279,18 @@ module.exports = function (grunt) { files: { "dist/css/ripples.css": "less/ripples.less", } + }, + docs: { + options: { + paths: ["less"], + sourceMap: true, + sourceMapRootpath: "/", + sourceMapFilename: "docs/assets/css/src/docs.css.map", + sourceMapURL: "docs.css.map" + }, + files: { + "docs/assets/css/src/docs.css": "docs/assets/css/src/docs.less", + } } }, @@ -213,36 +299,69 @@ module.exports = function (grunt) { autoprefixer: { options: { map: true, - browsers: ["last 3 versions", "ie 8", "ie 9", "ie 10", "ie 11"] + browsers: configBridge.config.autoprefixerBrowsers }, material: { files: { - "dist/css/material.css": "dist/css/material.css", - "dist/css/material.min.css": "dist/css/material.min.css" + "dist/css/material.css": "dist/css/material.css" } }, materialfullpalette: { files: { - "dist/css/material-fullpalette.css": "dist/css/material-fullpalette.css", - "dist/css/material-fullpalette.min.css": "dist/css/material-fullpalette.min.css" + "dist/css/material-fullpalette.css": "dist/css/material-fullpalette.css" } }, roboto: { files: { - "dist/css/roboto.css": "dist/css/roboto.css", - "dist/css/roboto.min.css": "dist/css/roboto.min.css" + "dist/css/roboto.css": "dist/css/roboto.css" } }, ripples: { files: { - "dist/css/ripples.css": "dist/css/ripples.css", - "dist/css/ripples.min.css": "dist/css/ripples.min.css" + "dist/css/ripples.css": "dist/css/ripples.css" } + }, + docs: { + src: ['docs/assets/css/src/docs.css'] + }, + examples: { + expand: true, + cwd: 'docs/examples/', + src: ['**/*.css'], + dest: 'docs/examples/' + } + }, + + csslint: { + options: { + csslintrc: 'less/.csslintrc' + }, + dist: [ + 'dist/css/material.css', + 'dist/css/material-fullpalette.css' + ], + examples: [ + 'docs/examples/**/*.css' + ], + docs: { + options: { + ids: false, + 'overqualified-elements': false + }, + src: 'docs/assets/css/src/docs.css' } }, // Minify CSS and adapt maps - csswring: { + cssmin: { + options: { + // TODO: disable `zeroUnits` optimization once clean-css 3.2 is released + // and then simplify the fix for https://github.com/twbs/bootstrap/issues/14837 accordingly + compatibility: 'ie8', + keepSpecialComments: '*', + sourceMap: true, + advanced: false + }, material: { src: "dist/css/material.css", dest: "dist/css/material.min.css" @@ -258,6 +377,14 @@ module.exports = function (grunt) { ripples: { src: "dist/css/ripples.css", dest: "dist/css/ripples.min.css" + }, + docs: { + src: [ + 'docs/assets/css/ie10-viewport-bug-workaround.css', + 'docs/assets/css/src/pygments-manni.css', + 'docs/assets/css/src/docs.css' + ], + dest: 'docs/assets/css/docs.min.css' } }, @@ -278,6 +405,14 @@ module.exports = function (grunt) { dest: "dist/fonts/", flatten: true, filter: "isFile" + }, + docs: { + expand: true, + cwd: 'dist/', + src: [ + '**/*' + ], + dest: 'docs/dist/' } }, @@ -295,6 +430,14 @@ module.exports = function (grunt) { files: { "dist/js/ripples.min.js": "dist/js/ripples.js" } + }, + customize: { + src: configBridge.paths.customizerJs, + dest: 'docs/assets/js/customize.min.js' + }, + docsJs: { + src: configBridge.paths.docsJs, + dest: 'docs/assets/js/docs.min.js' } }, @@ -333,43 +476,67 @@ module.exports = function (grunt) { }, jshint: { options: { - jshintrc: ".jshintrc", + jshintrc: "scripts/.jshintrc", reporter: require("jshint-stylish") }, - all: [ - //"Gruntfile.js", regex lines are too long for desired style guide. - "scripts/**/*.js", - "template/**/*.js", - "!template/**/*.min.js" - ], - test: { + grunt: { options: { - jshintrc: "test/.jshintrc", - src: ["test/**/*.js"] - } + jshintrc: 'grunt/.jshintrc' + }, + src: ['Gruntfile.js', 'package.js'] + }, + core: { + src: ["scripts/**/*.js"] + }, + test: { + src: ["test/**/*.js"] + }, + assets: { + options: { + jshintrc: "docs/assets/js/.jshintrc" + }, + src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js'] } }, + + jscs: { + options: { + config: 'scripts/.jscsrc' + }, + grunt: { + src: '<%= jshint.grunt.src %>' + }, + core: { + src: '<%= jshint.core.src %>' + }, + test: { + src: '<%= jshint.test.src %>' + }, + assets: { + options: { + requireCamelCaseOrUpperCaseIdentifiers: null + }, + src: '<%= jshint.assets.src %>' + } + }, + watch: { html: { files: ["index.html", "bootstrap-elements.html", "test.html"], tasks: ["htmllint", "bootlint"] }, - js: { - files: ["Gruntfile.js", "scripts/**/*.js", "template/**/*.js"], - tasks: ["newer:jshint:all", "material:js"] - }, - jsTest: { + //src: { + // files: '<%= jshint.core.src %>', + // tasks: ['jshint:core', 'dist-js'] // add tests when working again + //}, + test: { files: ["test/**/*.js"], - tasks: ["newer:jshint:test", "jasmine"] + tasks: ["jshint:test", "jasmine"] }, less: { files: ["less/**/*.less"], - tasks: ["material:less"]//, "material:sass"] + tasks: ["dist-less"] }, - //sass: { - // files: ["sass/*.scss"], - // tasks: ["material:sass"] - //}, livereload: { options: { livereload: "<%= connect.options.livereload %>" @@ -383,6 +550,26 @@ module.exports = function (grunt) { ] } }, + + compress: { + main: { + options: { + archive: 'bootstrap-material-design-<%= pkg.version %>-dist.zip', + mode: 'zip', + level: 9, + pretty: true + }, + files: [ + { + expand: true, + cwd: 'dist/', + src: ['**'], + dest: 'bootstrap-material-design-<%= pkg.version %>-dist' + } + ] + } + }, + exec: { "meteor-init": { command: [ @@ -413,83 +600,103 @@ module.exports = function (grunt) { }); - grunt.loadNpmTasks("grunt-less-to-sass"); - grunt.registerTask("default", ["material", "ripples"]); - - grunt.registerTask("material", [ - "material:less", - "material:js", - "material:fonts", - "material:sass" - ]); - - grunt.registerTask("material:sass", [ - "lessToSass:convert", - "sass:compile" - ]); - - grunt.registerTask("material:less", [ - "htmllint", - "bootlint", - "less:material", - "less:materialfullpalette", - "less:roboto", - "csswring:material", - "csswring:materialfullpalette", - "csswring:roboto", - "autoprefixer:material", - "autoprefixer:materialfullpalette", - "autoprefixer:roboto" - ]); - grunt.registerTask("material:js", [ - "copy:material", - "uglify:material" - ]); - grunt.registerTask("material:fonts", [ - "copy:fonts" - ]); - - grunt.registerTask("ripples", [ - "ripples:less", - "ripples:js" - ]); - grunt.registerTask("ripples:less", [ - "less:ripples", - "csswring:ripples", - "autoprefixer:ripples" - ]); - grunt.registerTask("ripples:js", [ - "copy:ripples", - "uglify:ripples" - ]); - - grunt.registerTask("build", function () { - grunt.task.run(["newer:jshint", "default"]); - }); + require('load-grunt-tasks')(grunt, {scope: 'devDependencies'}); + //require('time-grunt')(grunt); + grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']); grunt.registerTask("test", [ + "dist", "jasmine:scripts:build", "connect:test:keepalive" ]); - grunt.registerTask("serve", function (target) { - var buildTarget = "material:less"; - if (target && target === "scss") { - buildTarget = "scss"; - } - grunt.task.run([ - "build:" + buildTarget, - "connect:livereload", - "watch" - ]); - }); + // Docs HTML validation task + grunt.registerTask('validate-html', ['jekyll:docs', 'htmllint']); + + grunt.loadNpmTasks("grunt-less-to-sass"); + + // CSS distribution tasks + grunt.registerTask("dist-sass", [ + "lessToSass:convert", + "sass:compile" + ]); + + grunt.registerTask('less-compile', [ + "less:material", + "less:materialfullpalette", + "less:roboto", + "less:ripples" + ]); + + grunt.registerTask("dist-less", [ + "less-compile", + + "autoprefixer:material", + "autoprefixer:materialfullpalette", + "autoprefixer:roboto", + "autoprefixer:ripples", + + "cssmin:material", + "cssmin:materialfullpalette", + "cssmin:roboto", + "cssmin:ripples" + ]); + + grunt.registerTask("dist-js", [ + "jshint", + "copy:material", + "uglify:material", + "copy:ripples", + "uglify:ripples" + ]); + + grunt.registerTask("dist-fonts", [ + "copy:fonts" + ]); + + // Full distribution + grunt.registerTask("dist", [ + "clean:dist", + + "htmllint", + "bootlint", + + "dist-less", + "dist-js", + "dist-fonts", + "dist-sass" + ]); + + // Default task. + grunt.registerTask('default', ['dist']); // test as well when it works? + + + grunt.registerTask("serve", [ + "htmllint", + "bootlint", + "dist-less", + "dist-js", + "dist-fonts", + "connect:livereload", + "watch" + ]); // Meteor tasks grunt.registerTask("meteor-test", ["exec:meteor-init", "exec:meteor-test", "exec:meteor-cleanup"]); grunt.registerTask("meteor-publish", ["exec:meteor-init", "exec:meteor-publish", "exec:meteor-cleanup"]); grunt.registerTask("meteor", ["exec:meteor-init", "exec:meteor-test", "exec:meteor-publish", "exec:meteor-cleanup"]); - //grunt.registerTask("cibuild", ["newer:jshint", "meteor-test"]); - grunt.registerTask("cibuild", ["build"]); + + // Docs task. + grunt.registerTask('build-icons-data', function () { generateIconsData.call(this, grunt); }); + grunt.registerTask('docs-css', ['less:docs','autoprefixer:docs', 'autoprefixer:examples', 'cssmin:docs']); + grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']); + grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']); + grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']); + grunt.registerTask('docs', [ + 'docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-icons-data' + ]); + + grunt.registerTask('prep-release', ['dist', 'docs', 'jekyll:github', 'htmlmin']); //, 'compress']); }; diff --git a/LICENSE.md b/LICENSE.md index d11c4ef5..6cb0a77e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -19,3 +19,9 @@ 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. + + +Acknowledgements: + +# Some original Bootstrap code and documentation http://getbootstrap.com +Copyright (c) 2011-2015 Twitter, Inc diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..404a2e20 --- /dev/null +++ b/_config.yml @@ -0,0 +1,50 @@ +baseurl: "/bootstrap-material-design" +#url: "http://fezvrasta.github.io" +url: "http://rosskevin.github.io" + +include: + - .nojekyll + +gems: ['jekyll-less'] + +sass: + sass_dir: sass + +# Dependencies +markdown: kramdown +highlighter: rouge + +# Permalinks +permalink: pretty + +# Server +source: docs +destination: _gh_pages +host: 0.0.0.0 +port: 9001 +url: http://fezvrasta.github.io/bootstrap-material-design +encoding: UTF-8 + +# Custom vars +current_version: 0.4.1 +repo: https://github.com/fezvrasta/bootstrap-material-design +#sass_repo: https://github.com/fezvrasta/bootstrap-material-design-sass + +download: + source: https://github.com/fezvrasta/bootstrap-material-design/archive/v0.4.1.zip + dist: https://github.com/fezvrasta/bootstrap-material-design/releases/download/v0.4.1/bootstrap-0.4.1-dist.zip +# sass: https://github.com/fezvrasta/bootstrap-material-design-sass/archive/v0.4.1.tar.gz + +#blog: http://blog.getbootstrap.com +#expo: http://expo.getbootstrap.com +# +#cdn: +# # See https://www.srihash.org for info on how to generate the hashes +# css: https://maxcdn.bootstrapcdn.com/bootstrap/0.4.1/css/bootstrap.min.css +# css_hash: "sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" +# css_theme: https://maxcdn.bootstrapcdn.com/bootstrap/0.4.1/css/bootstrap-theme.min.css +# css_theme_hash: "sha384-aUGj/X2zp5rLCbBxumKTCw2Z50WgIr1vs/PFN4praOTvYXWlVyh2UtNUU0KAUhAX" +# js: https://maxcdn.bootstrapcdn.com/bootstrap/0.4.1/js/bootstrap.min.js +# js_hash: "sha512-K1qjQ+NcF2TYO/eI3M6v8EiNYZfA95pQumfvcVrTHtwQVDG+aHRqLi/ETn2uB+1JqwYqVG3LIvdm9lj6imS/pQ==" + + diff --git a/bootstrap-elements.html b/bootstrap-elements.html index 9a418b45..423cc195 100644 --- a/bootstrap-elements.html +++ b/bootstrap-elements.html @@ -286,7 +286,7 @@ ================================================== -->