Unverified Commit 6b2b8e56 authored by David Haynes's avatar David Haynes
Browse files

Merge branch '4-bootstrap4-sass-only'

parents 0814e8aa 05729599
Pipeline #1062 passed with stage
in 58 seconds
{
"scripts": {
"postinstall": "cp -a ./bower_components/bootstrap/fonts ./"
}
}
......@@ -15,5 +15,13 @@ Session.vim
*~
# auto-generated tag files
tags
masonstrap/masonstrap.css
masonstrap/masonstrap.min.css
masonstrap/*.css
masonstrap/*.min.css
.idea
components
node_modules
build
_site
*.lock
.sass-cache/
bower_components
image: node:4.2.6
image: node:7.6.0
build_css:
before_script:
- npm install -g grunt-cli
- npm install
- npm install -g grunt-cli
- npm install -g bower
- apt-get update
- apt-get install ruby -y
- gem install sass
- bower install --allow-root
script:
- grunt swatch:masonstrap
artifacts:
paths:
- masonstrap/masonstrap.min.css
pages:
stage: deploy
script:
- mkdir .public
- cp index.html masonstrap/masonstrap.min.css assets/css/custom.min.css bower_components/bootstrap/dist/js/bootstrap.min.js assets/js/custom.js .public
- mv .public public
- grunt build
artifacts:
paths:
- public
only:
- master
- masonstrap/masonstrap.min.css
\ No newline at end of file
......@@ -9,3 +9,24 @@ _config.yml
bower.json
Gruntfile.js
*/index.html
2/
3/
assets/
bower_components/
custom/
default/
global/
help/
tests/
_config.yml
.bowerrc
.gitignore
.travis.yml
bower.json
CNAME
composer.json
favicon.ico
Gemfile
Gruntfile.js
index.html
*/index.html
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
var configBridge = grunt.file.readJSON('./bower_components/bootstrap/grunt/configBridge.json', { encoding: 'utf8' });
grunt.loadNpmTasks('grunt-exec');
// Project configuration.
grunt.initConfig({
// Define some variables and options
pkg: grunt.file.readJSON('package.json'),
builddir: '.',
builddir: 'masonstrap/',
buildtheme: '',
banner: '/*!\n' +
' * <%= pkg.name %> v<%= pkg.version %>\n' +
' * Homepage: <%= pkg.homepage %>\n' +
' * Copyright 2012-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed under <%= pkg.license %>\n' +
' * Based on Bootstrap\n' +
' * Based on Bootstrap 4\n' +
'*/\n',
swatch: {
masonstrap:{}
},
clean: {
build: {
src: ['*/build.less', '*/build.scss', '!global/build.less', '!global/build.scss']
src: ['*/build.scss', '!assets/scss/build.scss']
}
},
concat: {
......@@ -39,31 +34,19 @@ module.exports = function (grunt) {
dest: ''
}
},
less: {
dist: {
options: {
compress: false,
strictMath: true
},
files: {}
}
},
autoprefixer: {
options: {
browsers: configBridge.config.autoprefixerBrowsers
},
dist: {
src: '*/masonstrap.css'
}
},
watch: {
files: ['*/variables.less', '*/bootswatch.less', '*/index.html'],
files: ['*/_variables.scss', '*/_masonstrap.scss', 'index.html', 'demo.html'],
tasks: 'build',
options: {
livereload: true,
nospawn: true
}
},
exec: {
postcss: {
command: 'npm run postcss'
}
},
connect: {
base: {
options: {
......@@ -83,173 +66,50 @@ module.exports = function (grunt) {
}
});
// Default task (does nothing)
grunt.registerTask('none', function() {});
grunt.registerTask('build', 'build a regular theme', function(theme, compress) {
var theme = theme == undefined ? grunt.config('buildtheme') : theme;
var compress = compress == undefined ? true : compress;
var isValidTheme = grunt.file.exists(theme, 'variables.less') && grunt.file.exists(theme, 'bootswatch.less');
// cancel the build (without failing) if this directory is not a valid theme
if (!isValidTheme) {
return;
}
var concatSrc;
var concatDest;
var lessDest;
var lessSrc;
var files = {};
var dist = {};
concatSrc = 'global/build.less';
concatDest = theme + '/build.less';
lessDest = '<%=builddir%>/' + theme + '/masonstrap.css';
lessSrc = [ theme + '/' + 'build.less' ];
dist = {src: concatSrc, dest: concatDest};
grunt.config('concat.dist', dist);
files = {}; files[lessDest] = lessSrc;
grunt.config('less.dist.files', files);
grunt.config('less.dist.options.compress', false);
grunt.task.run(['concat', 'less:dist', 'prefix:' + lessDest, 'clean:build',
compress ? 'compress:'+lessDest+':'+'<%=builddir%>/' + theme + '/masonstrap.min.css':'none']);
});
grunt.registerTask('build_scss', 'build a regular theme from scss', function(theme, compress) {
var theme = theme == undefined ? grunt.config('buildtheme') : theme;
var compress = compress == undefined ? true : compress;
var isValidTheme = grunt.file.exists(theme, '_variables.scss') && grunt.file.exists(theme, '_bootswatch.scss');
//
grunt.registerTask('build', 'build masonstrap from scss', function(compress) {
compress = compress === undefined ? true : compress;
// cancel the build (without failing) if this directory is not a valid theme
if (!isValidTheme) {
return;
}
var concatSrc;
var concatDest;
var scssDest;
var scssSrc;
var files = {};
var dist = {};
concatSrc = 'global/build.scss';
concatDest = theme + '/build.scss';
scssDest = '<%=builddir%>/' + theme + '/masonstrap.css';
scssSrc = [theme + '/' + 'build.scss'];
let concatSrc = 'assets/scss/build.scss';
let concatDest = 'masonstrap/build.scss';
let scssSrc = 'masonstrap/build.scss';
let scssDest = '<%=builddir%>/masonstrap.css';
let dist = {src: concatSrc, dest: concatDest};
let files = {}; files[scssDest] = scssSrc;
dist = {src: concatSrc, dest: concatDest};
// Set configs
grunt.config('concat.dist', dist);
files = {};
files[scssDest] = scssSrc;
grunt.config('sass.dist.files', files);
grunt.config('sass.dist.options.style', 'expanded');
grunt.config('sass.dist.options.sourcemap', 'none');
grunt.config('sass.dist.options.precision', 8);
grunt.config('sass.dist.options.unix-newlines', true);
grunt.task.run(['concat', 'sass:dist', 'prefix:' + scssDest, 'clean:build',
compress ? 'compress_scss:' + scssDest + ':' + '<%=builddir%>/' + theme + 'masonstrap.min.css' : 'none']);
});
grunt.registerTask('prefix', 'autoprefix a generic css', function(fileSrc) {
grunt.config('autoprefixer.dist.src', fileSrc);
grunt.task.run('autoprefixer');
});
grunt.registerTask('compress', 'compress a generic css', function(fileSrc, fileDst) {
var files = {}; files[fileDst] = fileSrc;
grunt.log.writeln('compressing file ' + fileSrc);
grunt.config('less.dist.files', files);
grunt.config('less.dist.options.compress', true);
grunt.task.run(['less:dist']);
//
grunt.task.run(['concat', 'sass:dist', 'exec:postcss', 'clean:build',
compress ? 'compress:' + scssDest + ':' + '<%=builddir%>/masonstrap.min.css' : 'none']);
});
grunt.registerTask('compress_scss', 'compress a generic css with sass', function(fileSrc, fileDst) {
//
grunt.registerTask('compress', 'compress a generic css with sass', function(fileSrc, fileDst) {
var files = {}; files[fileDst] = fileSrc;
grunt.log.writeln('compressing file ' + fileSrc);
grunt.config('sass.dist.files', files);
grunt.config('sass.dist.options.style', 'compressed');
grunt.task.run(['sass:dist']);
});
grunt.registerMultiTask('swatch', 'build a theme', function() {
var t = this.target;
grunt.task.run('build:'+t);
});
grunt.registerTask('swatch_scss', 'build a theme from scss ', function (theme) {
var t = theme;
if (!t) {
for (var t in grunt.config('swatch')) {
grunt.task.run('build_scss:' + t);
}
} else {
grunt.task.run('build_scss:' + t);
}
grunt.task.run(['sass:dist']);
});
grunt.event.on('watch', function(action, filepath) {
var path = require('path');
var theme = path.dirname(filepath);
grunt.config('buildtheme', theme);
grunt.config('buildtheme', 'masonstrap');
});
/**
* Regex borrowed form
* https://gist.github.com/rosskevin/ddfe895091de2ca5f931
* */
grunt.registerTask('convert_less', 'Convert less to scss using regular expression', function () {
var convertBaseDir = '';
grunt.file.expand(convertBaseDir + '*/*.less').forEach(function (lessFile) {
if (lessFile !=="global/build.less"){
var srcContents = grunt.file.read(lessFile);
var out = srcContents
// 1. replace @ with $
.replace(/@(?!import|media|keyframes|-)/g, '$')
// 2. replace mixins
.replace(/[\.#](?![0-9])([\w\-]*)\s*\((.*)\)\s*\{/g, '@mixin $1($2){')
// 3. In LESS, bootstrap namespaces mixins, in SASS they are just prefixed e.g #gradient > .vertical-three-colors becomes @include gradient-vertical-three-colors
.replace(/[\.#](?![0-9])([\w\-]*)\s>\s\.(.*;)/g, '@include $1-$2')
// 4. replace includes
.replace(/[\.#](?![0-9])([\w\-].*\(.*;)/g, '@include $1')
// 5. replace no param mixin includes with empty parens
.replace(/@include\s([\w\-]*\s*);/g, '@include $1();')
// 6. replace extends .class; @extend .class;
.replace(/(\.(?![0-9])([\w\-]+);)/g, '@extend $1')
// 7. replace string literals
.replace(/~"(.*)"/g, '#{"$1"}')
// 8. replace interpolation ${var} > #{$var}
.replace(/\$\{(.*)\}/g, '#{$$$1}')
// 9. replace spin to adjust-hue (function name diff)
.replace(/spin\(/g, 'adjust-hue(')
// 10. replace bower and imports in build.scss
.replace(/bootstrap\/less\//g, 'bootstrap-sass-official/assets/stylesheets/')
.replace(/\.less/g, '')
// 11. replace icon-font-path value with conditional for asset helpers
.replace(/(\$icon-font-path:).*;/g, '$1 if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/");')
// 12. set bootswatch's web-font-path value as !default
.replace(/(\$web-font-path:.*);/g, '$1 !default;')
// 13. Remove the web-font mixin which breaks in libsass
.replace(/[\s\S][\s\S]@mixin web-font.*([\s\S]*?).*;([\s\S]*?)}([\s\S]*?)/,"")
// 14. Replace usage of the web-font mixin with variable interpolation
.replace(/@include web-font/,'@import url');
if (/\/variables.less$/.test(lessFile)) {
// 15. set default value of $bootstrap-sass-asset-helper to false
out = "$bootstrap-sass-asset-helper: false;\n" + out;
// 16. only assign variables if they haven't been previously set e.g. $var: #f00; > $var: #f00 !default;
out = out.replace(/^(\$.*);/gm, '$1 !default;');
}
var baseDirRegex = new RegExp("^" + convertBaseDir, "g");
var sassFile = lessFile.replace(baseDirRegex, '').replace(/\.less$/, '.scss').replace(/(bootswatch|variables)/, '_$1');
grunt.file.write(sassFile, out);
grunt.log.writeln('Converted less file: ', lessFile, Array(27 - lessFile.length).join(' '),'> ', sassFile);
}
});
});
grunt.registerTask('postcss', 'exec:postcss');
grunt.registerTask('server', 'connect:keepalive');
......
The MIT License (MIT)
Copyright (c) 2016 SRCT
Copyright (c) 2017 SRCT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......
......@@ -2,11 +2,10 @@
A project of [GMU SRCT](http://srct.gmu.edu).
Masonstrap is a custom theme for bootstrap customized with GMU brand colors and
Masonstrap is a theme for bootstrap customized with GMU brand colors and
elements. It aims to easily provide any web project with Mason branding.
## Enabling Masonstrap for Your Project
<legend></legend>
# Adding Masonstrap to your project
This repo contains all of the necessary components to build and modify masonstrap
on your local machine. If you'd like just `masonstrap.min.css` head over to our
......@@ -14,57 +13,63 @@ on your local machine. If you'd like just `masonstrap.min.css` head over to our
latest build of the css.
Additionally this link should grab you the latest css build:
https://git.gmu.edu/srct/masonstrap/builds/artifacts/master/download?job=build_css
[https://git.gmu.edu/srct/masonstrap/builds/artifacts/master/download?job=build_css]()
Masonstrap bundles bootstrap 3.7 and normalize.css for you.
## Building Masonstrap
<legend></legend>
# Building Masonstrap
If you would like to make changes to values or behaviors in Masonstrap you will
need to do some quick setup.
1. Ensure node.js is installed:
On Ubuntu: `$ sudo apt-get install npm`
On Ubuntu:
sudo apt update
sudo apt install nodejs
sudo apt install npm
On macOS, make sure you have [Homebrew](http://brew.sh) then `$ brew install node`
On macOS:
1. make sure you have [Homebrew](http://brew.sh)
2. `brew install node`
On Windows, download it [here](https://nodejs.org/en/download/).
2. In the root directory of this project run:
2. You will also need Sass which is distributed as a ruby gem:
On Ubuntu:
`$ npm install`
sudo apt update
sudo apt install ruby
sudo gem install sass
3. You will also need to have Grunt installed globally on your system:
3. In the root directory of this project run:
`$ npm install -g grunt-cli`
npm install
bower install
4. Finally, run:
`$ grunt swatch:masonstrap` to build masonstrap.css and masonstrap.min.css.
grunt build
### Stylesheet test webpage
to build the css files (`masonstrap.css` and `masonstrap.min.css`) in the `masonstrap/` directory.
Run:
# Local development
`grunt`
If you would like to run the demo site on your local machine run:
to spin up a local server at [http://0.0.0.0:3000](http://0.0.0.0:3000) that
will host a test webpage displaying all of the masonstrap elements styled with
your locally built css files. It will also rebuild masonstrap when it detects
that changes have been made and livereload the page for you.
grunt
## Making changes to Masonstrap
This will spin up a local server at [127.0.0.1:3000]().
Masonstrap consists of two LESS files. `variables.less`, which is included by
default in Bootstrap, allows you to customize [these settings](http://getbootstrap.com/customize/#less-variables).
`bootswatch.less` introduces more extensive structural changes.
These files are also available in SASS.
Any changes made to the `.scss` or `.html` files will trigger a rebuild of the css and livereload of the site.
## Making changes to Masonstrap
Icon
------
website by Stock Image Folio from the Noun Project
Masonstrap consists of two Sass files. `_variables.scss`, which is included by
default in Bootstrap, allows you to customize [these settings](http://getbootstrap.com/customize/#less-variables).
`_masonstrap.scss` introduces more extensive structural changes.
exclude: ["src", "node_modules", "bower.json", "bower_components/font-awesome/src", "package.json", "README.md", "Gruntfile.js"]
exclude: ["src", "node_modules", "bower.json", "bower_components/font-awesome/src", "composer.json", "package.json", "README.md", "LICENSE", "Gruntfile.js", "Gemfile"]
include: ["_bootswatch.scss","_variables.scss"]
body{padding-top:50px}body>.navbar{-webkit-transition:background-color .3s ease-in;transition:background-color .3s ease-in}@media (min-width:768px){body>.navbar-transparent{background-color:transparent}body>.navbar-transparent .navbar-nav>.open>a{background-color:transparent!important}}#home{padding-top:0}#home .navbar-brand{padding:13.5px 15px 12.5px}#home .navbar-brand>img{display:inline;margin:0 10px;height:100%}#banner{min-height:300px;border-bottom:none}.table-of-contents{margin-top:1em}.page-header h1{font-size:4em}.bs-docs-section{margin-top:6em}.bs-docs-section h1{padding-top:100px}.bs-component{position:relative}.bs-component .modal{position:relative;top:auto;right:auto;left:auto;bottom:auto;z-index:1;display:block}.bs-component .modal-dialog{width:90%}.bs-component .popover{position:relative;display:inline-block;width:220px;margin:20px}#source-button{position:absolute;top:0;right:0;z-index:100;font-weight:700}.nav-tabs{margin-bottom:15px}.progress{margin-bottom:10px}footer{margin:5em 0}footer li{float:left;margin-right:1.5em;margin-bottom:1.5em}footer p{clear:left;margin-bottom:0}.splash{padding:9em 0 2em;background-color:#141d27;background-image:url(../img/bg.jpg);background-size:cover;background-attachment:fixed;color:#fff;text-align:center}.splash .logo{width:160px}.splash h1{font-size:3em}.splash #social{margin:2em 0}.splash .alert{margin:2em 0}.section-tout{padding:4em 0 3em;border-bottom:1px solid rgba(0,0,0,.05);background-color:#eaf1f1}.section-tout .fa{margin-right:.5em}.section-tout p{margin-bottom:3em}.section-preview{padding:4em 0 4em}.section-preview .preview{margin-bottom:4em;background-color:#eaf1f1}.section-preview .preview .image{position:relative}.section-preview .preview .image:before{box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);position:absolute;top:0;left:0;width:100%;height:100%;content:"";pointer-events:none}.section-preview .preview .options{padding:1em 2em 2em;border:1px solid rgba(0,0,0,.05);border-top:none;text-align:center}.section-preview .preview .options p{margin-bottom:2em}.section-preview .dropdown-menu{text-align:left}.section-preview .lead{margin-bottom:2em}@media (max-width:767px){.section-preview .image img{width:100%}}.sponsor #carbonads{max-width:240px;margin:0 auto}.sponsor .carbon-text{display:block;margin-top:1em;font-size:12px}.sponsor .carbon-poweredby{float:right;margin-top:1em;font-size:10px}@media (max-width:767px){.splash{padding-top:4em}.splash .logo{width:100px}.splash h1{font-size:2em}#banner{margin-bottom:2em;text-align:center}}
body {
padding-top: 100px
}
body>.navbar {
-webkit-transition: background-color .3s ease-in;
transition: background-color .3s ease-in
}
pre {
background: #f7f7f9
}
@media (min-width: 768px) {
body>.navbar-transparent {
background-color:transparent!important
}
body>.navbar-transparent .navbar-nav>.open>a {
background-color: transparent!important
}
}
#home {
padding-top: 0
}
#home .logo .nav-link {
display: inline-block;
margin-right: -30px
}
#home .logo img {
display: inline-block;
margin: 0 10px;
width: 20%
}
#banner {
min-height: 300px;
border-bottom: none
}
.table-of-contents {
margin-top: 1em
}
.bs-docs-section {
margin-top: 6em
}
.bs-docs-section .page-header h1 {
padding: 5rem 0 2rem;
font-size: 4em
}
.bs-component {
position: relative
}
.bs-component+.bs-component {
margin-top: 1rem
}
.bs-component .card {
margin-bottom: 1rem
}
.bs-component .modal {
position: relative;
top: auto;
right: auto;
left: auto;
bottom: auto;
z-index: 1;
display: block
}
.bs-component .modal-dialog {
width: 90%
}
.bs-component .popover {
position: relative;
display: inline-block;
width: 220px;
margin: 20px
}
#source-button {
position: absolute;
top: 0;
right: 0;
z-index: 100;
font-weight: 700
}
.nav-tabs {
margin-bottom: 15px
}
.progress {
margin-bottom: 10px
}
#footer {
margin: 3em 0
}
#footer li {
float: left;
margin-right: 1.5em;
margin-bottom: 1.5em
}
#footer p {
clear: left;
margin-bottom: 0
}
.section-tout {
padding: 5em 0 2em;
border-bottom: 1px solid rgba(0,0,0,.05);
background-color: #eaf1f1
}
.section-tout .fa {
margin-right: .5em
}
.section-tout p {
margin-bottom: 3em