2013-05-14 19:12:01 +02:00
|
|
|
var path = require('path');
|
2013-05-09 23:56:32 +02:00
|
|
|
|
|
|
|
module.exports = function (grunt) {
|
|
|
|
|
|
|
|
// -- Config -------------------------------------------------------------------
|
|
|
|
|
|
|
|
grunt.initConfig({
|
|
|
|
|
2013-05-23 15:44:48 +02:00
|
|
|
pkg : grunt.file.readJSON('package.json'),
|
|
|
|
normalize: grunt.file.readJSON('src/base/bower.json'),
|
2013-05-09 23:56:32 +02:00
|
|
|
|
|
|
|
// -- Constants ------------------------------------------------------------
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
BUILD_COMMENT: 'THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT!',
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-13 20:56:23 +02:00
|
|
|
// -- Clean Config ---------------------------------------------------------
|
|
|
|
|
|
|
|
clean: {
|
2013-05-14 19:12:01 +02:00
|
|
|
build : ['build/'],
|
|
|
|
build_res: ['build/*-r.css'],
|
2013-05-14 21:58:25 +02:00
|
|
|
release : ['release/<%= pkg.version %>/'],
|
2013-05-23 15:44:48 +02:00
|
|
|
base : ['src/base/css/', 'src/base/bower.json', 'src/base/LICENSE.md']
|
2013-05-13 20:56:23 +02:00
|
|
|
},
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
// -- Copy Config ----------------------------------------------------------
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
copy: {
|
|
|
|
build: {
|
|
|
|
expand : true,
|
|
|
|
flatten: true,
|
|
|
|
src : 'src/**/css/*.css',
|
|
|
|
dest : 'build/',
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
rename: function (dest, src) {
|
|
|
|
// normalize -> base
|
|
|
|
src = src.replace(/^normalize(-.+\.css|\.css)$/, 'base$1');
|
|
|
|
return path.join(dest, src);
|
2013-05-09 23:56:32 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
normalize: {
|
|
|
|
expand : true,
|
|
|
|
flatten: true,
|
2013-05-23 14:54:51 +02:00
|
|
|
cwd : 'bower_components/normalize-css/',
|
2013-05-23 15:44:48 +02:00
|
|
|
src : '{bower.json,LICENSE.md,normalize.css}',
|
2013-05-14 19:12:01 +02:00
|
|
|
dest : 'src/base/',
|
|
|
|
|
|
|
|
rename: function (dest, file) {
|
|
|
|
if (grunt.file.isMatch('*.css', file)) {
|
|
|
|
return path.join(dest, 'css', file);
|
|
|
|
}
|
|
|
|
|
|
|
|
return path.join(dest, file);
|
|
|
|
},
|
|
|
|
|
|
|
|
options: {
|
|
|
|
processContent: function (content, file) {
|
|
|
|
var comment = grunt.config('BUILD_COMMENT');
|
|
|
|
|
|
|
|
if (grunt.file.isMatch({matchBase: true}, '*.css', file)) {
|
|
|
|
content = '/* ' + comment + ' */\n' + content;
|
|
|
|
} else if (grunt.file.isMatch({matchBase: true}, '*.html', file)) {
|
|
|
|
content = '<!-- ' + comment + ' -->\n' + content;
|
|
|
|
}
|
|
|
|
|
|
|
|
return content;
|
|
|
|
}
|
2013-05-09 23:56:32 +02:00
|
|
|
}
|
2013-05-14 19:12:01 +02:00
|
|
|
}
|
|
|
|
},
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
// -- Concat Config --------------------------------------------------------
|
|
|
|
|
|
|
|
concat: {
|
|
|
|
build: {
|
|
|
|
files: [
|
|
|
|
{'build/buttons.css': [
|
|
|
|
'build/buttons-core.css',
|
|
|
|
'build/buttons.css'
|
|
|
|
]},
|
|
|
|
|
|
|
|
{'build/forms-nr.css': [
|
|
|
|
'build/forms-core.css',
|
|
|
|
'build/forms.css'
|
|
|
|
]},
|
|
|
|
|
|
|
|
{'build/forms.css': [
|
|
|
|
'build/forms-nr.css',
|
|
|
|
'build/forms-r.css'
|
|
|
|
]},
|
|
|
|
|
|
|
|
{'build/grids-nr.css': [
|
2013-05-14 19:58:31 +02:00
|
|
|
'build/grids-core.css',
|
2013-05-14 19:12:01 +02:00
|
|
|
'build/grids-units.css'
|
|
|
|
]},
|
|
|
|
|
|
|
|
{'build/grids.css': [
|
|
|
|
'build/grids-nr.css',
|
|
|
|
'build/grids-r.css'
|
|
|
|
]},
|
|
|
|
|
|
|
|
{'build/menus-nr.css': [
|
|
|
|
'build/menus-core.css',
|
|
|
|
'build/menus.css',
|
|
|
|
'build/menus-paginator.css'
|
|
|
|
]},
|
|
|
|
|
|
|
|
{'build/menus.css': [
|
|
|
|
'build/menus-nr.css',
|
|
|
|
'build/menus-r.css'
|
|
|
|
]}
|
|
|
|
]
|
2013-05-09 23:56:32 +02:00
|
|
|
},
|
|
|
|
|
2013-05-16 19:01:32 +02:00
|
|
|
all: {
|
2013-05-09 23:56:32 +02:00
|
|
|
files: {
|
2013-05-16 19:01:32 +02:00
|
|
|
'build/<%= pkg.name %>-min.css': [
|
2013-05-14 19:12:01 +02:00
|
|
|
'build/base-min.css',
|
|
|
|
'build/buttons-min.css',
|
|
|
|
'build/forms-min.css',
|
|
|
|
'build/grids-min.css',
|
|
|
|
'build/menus-min.css',
|
|
|
|
'build/tables-min.css'
|
|
|
|
],
|
|
|
|
|
2013-05-16 19:01:32 +02:00
|
|
|
'build/<%= pkg.name %>-nr-min.css': [
|
2013-05-14 19:12:01 +02:00
|
|
|
'build/base-min.css',
|
|
|
|
'build/buttons-min.css',
|
|
|
|
'build/forms-nr-min.css',
|
|
|
|
'build/grids-nr-min.css',
|
|
|
|
'build/menus-nr-min.css',
|
|
|
|
'build/tables-min.css'
|
|
|
|
]
|
2013-05-09 23:56:32 +02:00
|
|
|
}
|
2013-05-14 19:12:01 +02:00
|
|
|
}
|
|
|
|
},
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-06-05 15:25:13 +02:00
|
|
|
// -- CSSLint Config -------------------------------------------------------
|
|
|
|
|
|
|
|
csslint: {
|
|
|
|
options: {
|
|
|
|
csslintrc: '.csslintrc'
|
|
|
|
},
|
|
|
|
|
|
|
|
src: {
|
|
|
|
src: [
|
|
|
|
'src/**/css/*.css',
|
|
|
|
'!src/base/css/*',
|
|
|
|
'!src/forms/css/forms-core.css'
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
// -- CSSMin Config --------------------------------------------------------
|
|
|
|
|
|
|
|
cssmin: {
|
|
|
|
options: {
|
|
|
|
// report: 'gzip'
|
2013-05-09 23:56:32 +02:00
|
|
|
},
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
files: {
|
|
|
|
expand: true,
|
|
|
|
src : 'build/*.css',
|
|
|
|
ext : '-min.css'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-14 21:58:25 +02:00
|
|
|
// -- Compress Config ------------------------------------------------------
|
|
|
|
|
|
|
|
compress: {
|
|
|
|
release: {
|
|
|
|
options: {
|
|
|
|
archive: 'release/<%= pkg.version %>/<%= pkg.name %>-<%= pkg.version %>.zip'
|
|
|
|
},
|
|
|
|
|
|
|
|
expand : true,
|
|
|
|
flatten: true,
|
|
|
|
src : 'build/*.css',
|
|
|
|
dest : '<%= pkg.name %>/<%= pkg.version %>/'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-14 22:59:18 +02:00
|
|
|
// -- License Config -------------------------------------------------------
|
|
|
|
|
|
|
|
license: {
|
|
|
|
normalize: {
|
|
|
|
options: {
|
|
|
|
banner: [
|
|
|
|
'/*!',
|
2013-05-23 15:44:48 +02:00
|
|
|
'normalize.css v<%= normalize.version %> | MIT License | git.io/normalize',
|
2013-05-14 22:59:18 +02:00
|
|
|
'Copyright (c) Nicolas Gallagher and Jonathan Neal',
|
|
|
|
'*/\n'
|
|
|
|
].join('\n')
|
|
|
|
},
|
|
|
|
|
|
|
|
expand: true,
|
|
|
|
cwd : 'build/',
|
2013-05-16 19:01:32 +02:00
|
|
|
src : ['base*.css', 'forms*.css', 'tables*.css', '<%= pkg.name %>*.css']
|
2013-05-14 22:59:18 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
yahoo: {
|
|
|
|
options: {
|
|
|
|
banner: [
|
|
|
|
'/*!',
|
2013-05-23 15:44:48 +02:00
|
|
|
'Pure v<%= pkg.version %>',
|
2013-05-14 22:59:18 +02:00
|
|
|
'Copyright 2013 Yahoo! Inc. All rights reserved.',
|
|
|
|
'Licensed under the BSD License.',
|
2013-05-16 19:01:32 +02:00
|
|
|
'https://github.com/yui/pure/blob/master/LICENSE.md',
|
2013-05-14 22:59:18 +02:00
|
|
|
'*/\n'
|
|
|
|
].join('\n')
|
|
|
|
},
|
|
|
|
|
|
|
|
expand: true,
|
|
|
|
src : ['build/*.css']
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
// -- Contextualize Config -------------------------------------------------
|
|
|
|
|
|
|
|
contextualize: {
|
|
|
|
normalize: {
|
|
|
|
src : 'src/base/css/normalize.css',
|
|
|
|
dest: 'src/base/css/normalize-context.css',
|
|
|
|
|
|
|
|
options: {
|
2013-05-16 19:34:29 +02:00
|
|
|
prefix: '.pure',
|
2013-05-14 22:59:18 +02:00
|
|
|
banner: '/* <%= BUILD_COMMENT %> */\n'
|
2013-05-09 23:56:32 +02:00
|
|
|
}
|
|
|
|
}
|
2013-06-06 00:51:10 +02:00
|
|
|
},
|
|
|
|
|
2013-06-07 19:00:35 +02:00
|
|
|
// -- Watch/Observe Config -------------------------------------------------
|
2013-06-06 00:51:10 +02:00
|
|
|
|
2013-06-07 19:00:35 +02:00
|
|
|
observe: {
|
2013-06-06 00:51:10 +02:00
|
|
|
src: {
|
|
|
|
files: 'src/**/css/*.css',
|
2013-06-07 19:00:35 +02:00
|
|
|
tasks: ['test', 'suppress', 'default'],
|
2013-06-06 00:51:10 +02:00
|
|
|
|
|
|
|
options: {
|
|
|
|
interrupt: true
|
|
|
|
}
|
|
|
|
}
|
2013-05-09 23:56:32 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// -- Main Tasks ---------------------------------------------------------------
|
|
|
|
|
2013-05-13 20:56:23 +02:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-clean');
|
2013-05-14 19:12:01 +02:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-copy');
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-concat');
|
2013-06-05 15:25:13 +02:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-csslint');
|
2013-05-09 23:56:32 +02:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
2013-05-14 21:58:25 +02:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-compress');
|
2013-06-06 00:51:10 +02:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-13 20:56:23 +02:00
|
|
|
grunt.registerTask('default', [
|
|
|
|
'clean:build',
|
2013-05-14 19:12:01 +02:00
|
|
|
'copy:build',
|
|
|
|
'concat:build',
|
|
|
|
'clean:build_res',
|
|
|
|
'cssmin',
|
2013-05-16 19:01:32 +02:00
|
|
|
'concat:all',
|
2013-05-14 22:59:18 +02:00
|
|
|
'license'
|
2013-05-13 20:56:23 +02:00
|
|
|
]);
|
|
|
|
|
2013-06-07 19:00:35 +02:00
|
|
|
grunt.registerTask('test', [
|
|
|
|
'csslint'
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Makes the `watch` task run a build first.
|
|
|
|
grunt.renameTask('watch', 'observe');
|
|
|
|
grunt.registerTask('watch', ['default', 'observe']);
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
grunt.registerTask('import', [
|
2013-05-23 14:54:51 +02:00
|
|
|
'bower-install',
|
2013-05-14 19:12:01 +02:00
|
|
|
'import-normalize'
|
|
|
|
]);
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-14 21:58:25 +02:00
|
|
|
grunt.registerTask('release', [
|
2013-06-05 15:25:13 +02:00
|
|
|
'test',
|
2013-05-14 21:58:25 +02:00
|
|
|
'default',
|
|
|
|
'clean:release',
|
|
|
|
'compress:release'
|
|
|
|
]);
|
|
|
|
|
2013-06-07 19:00:35 +02:00
|
|
|
// -- Suppress Task ------------------------------------------------------------
|
|
|
|
|
|
|
|
grunt.registerTask('suppress', function () {
|
|
|
|
var allowed = ['success', 'fail', 'warn', 'error'];
|
|
|
|
|
|
|
|
grunt.util.hooker.hook(grunt.log, {
|
|
|
|
passName: true,
|
|
|
|
|
|
|
|
pre: function (name) {
|
|
|
|
if (allowed.indexOf(name) === -1) {
|
|
|
|
grunt.log.muted = true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
post: function () {
|
|
|
|
grunt.log.muted = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-05-09 23:56:32 +02:00
|
|
|
// -- Import Tasks -------------------------------------------------------------
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
grunt.registerTask('import-normalize', [
|
|
|
|
'clean:base',
|
|
|
|
'copy:normalize',
|
|
|
|
'contextualize:normalize'
|
|
|
|
]);
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-23 14:54:51 +02:00
|
|
|
// -- Bower Task ---------------------------------------------------------------
|
|
|
|
|
|
|
|
grunt.registerTask('bower-install', 'Installs Bower dependencies.', function () {
|
|
|
|
var bower = require('bower'),
|
|
|
|
done = this.async();
|
|
|
|
|
|
|
|
bower.commands.install()
|
|
|
|
.on('data', function (data) { grunt.log.write(data); })
|
|
|
|
.on('end', done);
|
|
|
|
});
|
|
|
|
|
2013-05-14 22:59:18 +02:00
|
|
|
// -- License Task -------------------------------------------------------------
|
|
|
|
|
|
|
|
grunt.registerMultiTask('license', 'Stamps license banners on files.', function () {
|
|
|
|
var options = this.options({banner: ''}),
|
|
|
|
banner = grunt.template.process(options.banner),
|
|
|
|
tally = 0;
|
|
|
|
|
|
|
|
this.files.forEach(function (filePair) {
|
|
|
|
filePair.src.forEach(function (file) {
|
|
|
|
grunt.file.write(file, banner + grunt.file.read(file));
|
|
|
|
tally += 1;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-05-30 02:01:33 +02:00
|
|
|
grunt.log.writeln('Stamped license on ' + String(tally).cyan + ' files.');
|
2013-05-14 22:59:18 +02:00
|
|
|
});
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
// -- Contextualize Task -------------------------------------------------------
|
2013-05-09 23:56:32 +02:00
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
grunt.registerMultiTask('contextualize', 'Makes Contextualized CSS files.', function () {
|
|
|
|
var Parser = require('parserlib').css.Parser,
|
|
|
|
done = this.async(),
|
|
|
|
options = this.options({banner: ''}),
|
|
|
|
banner = grunt.template.process(options.banner),
|
|
|
|
processing = 0;
|
2013-05-13 20:56:23 +02:00
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
function oneDone() {
|
|
|
|
if (!(processing -= 1)) {
|
|
|
|
done();
|
|
|
|
}
|
2013-05-13 20:56:23 +02:00
|
|
|
}
|
|
|
|
|
2013-05-14 19:12:01 +02:00
|
|
|
this.files.forEach(function (filePair) {
|
|
|
|
filePair.src.forEach(function (file) {
|
|
|
|
var src = grunt.file.read(file),
|
|
|
|
contextual = banner,
|
|
|
|
parser = new Parser();
|
|
|
|
|
|
|
|
parser.addListener('endstylesheet', function () {
|
|
|
|
grunt.file.write(filePair.dest, contextual);
|
|
|
|
grunt.log.writeln('File "' + filePair.dest + '" created.');
|
|
|
|
oneDone();
|
|
|
|
});
|
|
|
|
|
|
|
|
// Fired right before CSS properties are parsed for a certain rule.
|
|
|
|
// Go through and add all the selectors to the `css` string.
|
|
|
|
parser.addListener('startrule', function (event) {
|
|
|
|
var prefix = options.prefix;
|
|
|
|
|
|
|
|
event.selectors.forEach(function (selector, i) {
|
|
|
|
var nextSelector = event.selectors[i + 1];
|
|
|
|
|
|
|
|
// If the selector does not contain the html selector, we
|
2013-05-16 19:34:29 +02:00
|
|
|
// can go ahead and prepend `prefix` in front of it.
|
2013-05-14 19:12:01 +02:00
|
|
|
if (selector.text.indexOf('html') === -1) {
|
|
|
|
contextual += prefix + ' ' + selector.text;
|
|
|
|
} else if (selector.text.indexOf('html') !== -1) {
|
2013-05-16 19:34:29 +02:00
|
|
|
// If it contains `html`, replace the `html` with the
|
|
|
|
// `prefix`. Replace multiple spaces with a single
|
|
|
|
// space. This is for the case where
|
|
|
|
// `html input[type='button']` comes through as
|
|
|
|
// `html input[type='button']`.
|
2013-05-14 19:12:01 +02:00
|
|
|
contextual += selector.text.replace('html', prefix).replace(/ +/g, ' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
// If theres another selector, add a comma.
|
|
|
|
if (nextSelector) {
|
|
|
|
contextual += ',\n';
|
|
|
|
} else {
|
|
|
|
// Otherwise, add an opening bracket for properties
|
|
|
|
contextual += ' {\n';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// Fired right after CSS properties are parsed for a certain rule.
|
|
|
|
// Add the closing bracket to end the CSS Rule.
|
|
|
|
parser.addListener('endrule', function (event) {
|
|
|
|
contextual += '}\n';
|
|
|
|
});
|
|
|
|
|
|
|
|
// Fired for each property that the parser encounters. Add these
|
|
|
|
// properties to the `css` string with 4 spaces.
|
|
|
|
parser.addListener('property', function (event) {
|
|
|
|
// Add 4 spaces tab.
|
|
|
|
contextual += ' ' + event.property + ': ' + event.value + ';\n';
|
|
|
|
});
|
|
|
|
|
|
|
|
// Do the parsing.
|
|
|
|
processing += 1;
|
|
|
|
parser.parse(src);
|
2013-05-09 23:56:32 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|