Update Semantic to 2.1

Ticket #56
This commit is contained in:
Tim Schumacher 2016-06-10 00:34:34 +02:00
parent 3f1e728781
commit 4385f1acbc
425 changed files with 59924 additions and 37200 deletions

View file

@ -13,5 +13,5 @@ These tasks can be imported into your own gulpfile allowing you to avoid using S
var
watch = require('path/to/semantic/tasks/watch')
;
gulp.task('watch ui', 'Watch Semantic UI', watch));
```
gulp.task('watch ui', watch);
```

View file

@ -93,8 +93,8 @@ module.exports = function(callback) {
unrelatedNotes : new RegExp('^((?!(^.*(' + component + ').*$|###.*)).)*$', 'gmi'),
whitespace : /\n\s*\n\s*\n/gm,
// npm
export : /\$\.fn\.\w+\s*=\s*function\(parameters\)\s*{/g,
formExport : /\$\.fn\.\w+\s*=\s*function\(fields, parameters\)\s*{/g,
componentExport : /(.*)\$\.fn\.\w+\s*=\s*function\(([^\)]*)\)\s*{/g,
componentReference: '$.fn.' + component,
settingsExport : /\$\.fn\.\w+\.settings\s*=/g,
settingsReference : /\$\.fn\.\w+\.settings/g,
trailingComma : /,(?=[^,]*$)/,
@ -111,8 +111,8 @@ module.exports = function(callback) {
unrelatedNotes : '',
whitespace : '\n\n',
// npm
export : 'module.exports = function(parameters) {\n var _module = module;\n',
formExport : 'module.exports = function(fields, parameters) {\n var _module = module;\n',
componentExport : 'var _module = module;\n$1module.exports = function($2) {',
componentReference: '_module.exports',
settingsExport : 'module.exports.settings =',
settingsReference : '_module.exports.settings',
jQuery : 'require("jquery")'
@ -151,8 +151,8 @@ module.exports = function(callback) {
return gulp.src(release.source + component + '!(*.min|*.map).js')
.pipe(plumber())
.pipe(flatten())
.pipe(replace(regExp.match.export, regExp.replace.export))
.pipe(replace(regExp.match.formExport, regExp.replace.formExport))
.pipe(replace(regExp.match.componentExport, regExp.replace.componentExport))
.pipe(replace(regExp.match.componentReference, regExp.replace.componentReference))
.pipe(replace(regExp.match.settingsExport, regExp.replace.settingsExport))
.pipe(replace(regExp.match.settingsReference, regExp.replace.settingsReference))
.pipe(replace(regExp.match.jQuery, regExp.replace.jQuery))
@ -212,24 +212,24 @@ module.exports = function(callback) {
return gulp.src(release.templates.package)
.pipe(plumber())
.pipe(flatten())
.pipe(jsonEditor(function(package) {
.pipe(jsonEditor(function(npm) {
if(isJavascript) {
package.dependencies = {
npm.dependencies = {
jquery: 'x.x.x'
};
package.main = 'index.js';
npm.main = 'index.js';
}
package.name = packageName;
npm.name = packageName;
if(version) {
package.version = version;
npm.version = version;
}
package.title = 'Semantic UI - ' + capitalizedComponent;
package.description = 'Single component release of ' + component;
package.repository = {
npm.title = 'Semantic UI - ' + capitalizedComponent;
npm.description = 'Single component release of ' + component;
npm.repository = {
type : 'git',
url : gitURL
};
return package;
return npm;
}))
.pipe(gulp.dest(outputDirectory))
;
@ -329,4 +329,4 @@ module.exports = function(callback) {
}
runSequence(tasks, callback);
};
};

View file

@ -116,7 +116,7 @@ module.exports = function(callback) {
function commitFiles() {
// commit files
console.info('Committing ' + component + ' files', commitArgs);
gulp.src('**/*', gitOptions)
gulp.src('./', gitOptions)
.pipe(git.add(gitOptions))
.pipe(git.commit(commitMessage, commitOptions))
.on('error', function(error) {

View file

@ -94,7 +94,7 @@ module.exports = function(callback) {
'package.json',
'bower.json',
'.gitignore'
]
],
files = []
;
list.forEach(function(file) {
@ -111,14 +111,14 @@ module.exports = function(callback) {
files.push(filePath.replace(outputDirectory + path.sep, ''));
}
}
})
return files
});
return files;
};
// spaces out list correctly
createList = function(files) {
var filenames = '';
for(file in files) {
for(var file in files) {
if(file == (files.length - 1) ) {
filenames += "'" + files[file] + "'";
}
@ -132,7 +132,7 @@ module.exports = function(callback) {
gulp.task(task.meteor, function() {
var
files = gatherFiles(outputDirectory)
files = gatherFiles(outputDirectory),
filenames = createList(files)
;
gulp.src(release.templates.meteor[distLowerCase])
@ -149,7 +149,7 @@ module.exports = function(callback) {
gulp.task(task.repo, function() {
var
themes,
component,
components,
releases
;
themes = gulp.src('dist/themes/default/**/*', { base: 'dist/' })
@ -176,6 +176,9 @@ module.exports = function(callback) {
definitions = gulp.src('src/definitions/**/*', { base: 'src/' })
.pipe(gulp.dest(outputDirectory))
;
themeImport = gulp.src('src/semantic.less', { base: 'src/' })
.pipe(gulp.dest(outputDirectory))
;
themeImport = gulp.src('src/theme.less', { base: 'src/' })
.pipe(gulp.dest(outputDirectory))
;

View file

@ -65,18 +65,17 @@ module.exports = function(callback) {
}
var
component = release.distributions[index],
lowerCaseComponent = component.toLowerCase(),
outputDirectory = path.resolve(release.outputRoot + lowerCaseComponent),
repoName = release.distRepoRoot + component,
component = release.distributions[index],
lowerCaseComponent = component.toLowerCase(),
outputDirectory = path.resolve(release.outputRoot + lowerCaseComponent),
repoName = release.distRepoRoot + component,
gitOptions = { cwd: outputDirectory },
pullOptions = { args: '-q', cwd: outputDirectory, quiet: true },
resetOptions = { args: '-q --hard', cwd: outputDirectory, quiet: true },
gitURL = 'https://github.com/' + release.org + '/' + repoName + '.git',
repoURL = 'https://github.com/' + release.org + '/' + repoName + '/',
localRepoSetup = fs.existsSync(path.join(outputDirectory, '.git'))
gitOptions = { cwd: outputDirectory },
pullOptions = { args: '-q', cwd: outputDirectory, quiet: true },
resetOptions = { args: '-q --hard', cwd: outputDirectory, quiet: true },
gitURL = 'git@github.com:' + release.org + '/' + repoName + '.git',
repoURL = 'https://github.com/' + release.org + '/' + repoName + '/',
localRepoSetup = fs.existsSync(path.join(outputDirectory, '.git'))
;
console.log('Processing repository: ' + outputDirectory);

View file

@ -67,9 +67,6 @@ module.exports = function(callback) {
outputDirectory = path.resolve(path.join(release.outputRoot, distribution.toLowerCase() )),
repoName = release.distRepoRoot + distribution,
gitURL = 'https://github.com/' + release.org + '/' + repoName + '.git',
repoURL = 'https://github.com/' + release.org + '/' + repoName + '/',
commitArgs = (oAuth.name !== undefined && oAuth.email !== undefined)
? '--author "' + oAuth.name + ' <' + oAuth.email + '>"'
: '',
@ -114,7 +111,7 @@ module.exports = function(callback) {
function commitFiles() {
// commit files
console.info('Committing ' + distribution + ' files', commitArgs);
gulp.src('**/*', gitOptions)
gulp.src('./', gitOptions)
.pipe(git.add(gitOptions))
.pipe(git.commit(commitMessage, commitOptions))
.on('error', function(error) {

View file

@ -3,135 +3,48 @@
*******************************/
var
gulp = require('gulp'),
// node dependencies
console = require('better-console'),
fs = require('fs'),
// gulp dependencies
autoprefixer = require('gulp-autoprefixer'),
chmod = require('gulp-chmod'),
clone = require('gulp-clone'),
flatten = require('gulp-flatten'),
gulpif = require('gulp-if'),
less = require('gulp-less'),
minifyCSS = require('gulp-minify-css'),
plumber = require('gulp-plumber'),
print = require('gulp-print'),
rename = require('gulp-rename'),
replace = require('gulp-replace'),
uglify = require('gulp-uglify'),
// dependencies
gulp = require('gulp-help')(require('gulp')),
runSequence = require('run-sequence'),
// config
config = require('./config/user'),
tasks = require('./config/project/tasks'),
install = require('./config/project/install'),
// shorthand
globs = config.globs,
assets = config.paths.assets,
output = config.paths.output,
source = config.paths.source,
banner = tasks.banner,
comments = tasks.regExp.comments,
log = tasks.log,
settings = tasks.settings
// task sequence
tasks = []
;
// add internal tasks (concat release)
require('./collections/internal')(gulp);
// sub-tasks
if(config.rtl) {
require('./collections/rtl')(gulp);
}
require('./collections/build')(gulp);
module.exports = function(callback) {
var
stream,
compressedStream,
uncompressedStream
;
console.info('Building Semantic');
if( !install.isSetup() ) {
console.error('Cannot build files. Run "gulp install" to set-up Semantic');
console.error('Cannot find semantic.json. Run "gulp install" to set-up Semantic');
return;
}
// check for right-to-left language
// check for right-to-left (RTL) language
if(config.rtl === true || config.rtl === 'Yes') {
gulp.start('build-rtl');
return;
}
// unified css stream
stream = gulp.src(source.definitions + '/**/' + globs.components + '.less')
.pipe(plumber())
.pipe(less(settings.less))
.pipe(autoprefixer(settings.prefix))
.pipe(replace(comments.variables.in, comments.variables.out))
.pipe(replace(comments.license.in, comments.license.out))
.pipe(replace(comments.large.in, comments.large.out))
.pipe(replace(comments.small.in, comments.small.out))
.pipe(replace(comments.tiny.in, comments.tiny.out))
.pipe(flatten())
;
if(config.rtl == 'both') {
tasks.push('build-rtl');
}
// two concurrent streams from same source to concat release
uncompressedStream = stream.pipe(clone());
compressedStream = stream.pipe(clone());
tasks.push('build-javascript');
tasks.push('build-css');
tasks.push('build-assets');
// uncompressed component css
uncompressedStream
.pipe(plumber())
.pipe(replace(assets.source, assets.uncompressed))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(gulp.dest(output.uncompressed))
.pipe(print(log.created))
.on('end', function() {
gulp.start('package uncompressed css');
})
;
// compressed component css
compressedStream = stream
.pipe(plumber())
.pipe(clone())
.pipe(replace(assets.source, assets.compressed))
.pipe(minifyCSS(settings.minify))
.pipe(rename(settings.rename.minCSS))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(gulp.dest(output.compressed))
.pipe(print(log.created))
.on('end', function() {
callback();
gulp.start('package compressed css');
})
;
// copy assets
gulp.src(source.themes + '/**/assets/**/' + globs.components + '?(s).*')
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(gulp.dest(output.themes))
;
// copy source javascript
gulp.src(source.definitions + '/**/' + globs.components + '.js')
.pipe(plumber())
.pipe(flatten())
.pipe(replace(comments.license.in, comments.license.out))
.pipe(gulp.dest(output.uncompressed))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(print(log.created))
.pipe(uglify(settings.uglify))
.pipe(rename(settings.rename.minJS))
.pipe(gulp.dest(output.compressed))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(print(log.created))
.on('end', function() {
gulp.start('package compressed js');
gulp.start('package uncompressed js');
})
;
};
runSequence(tasks, callback);
};

View file

@ -0,0 +1,35 @@
/*******************************
Build Task
*******************************/
var
gulp = require('gulp'),
// gulp dependencies
chmod = require('gulp-chmod'),
gulpif = require('gulp-if'),
// config
config = require('../config/user'),
tasks = require('../config/tasks'),
// shorthand
globs = config.globs,
assets = config.paths.assets,
output = config.paths.output,
source = config.paths.source,
log = tasks.log
;
module.exports = function(callback) {
console.info('Building assets');
// copy assets
return gulp.src(source.themes + '/**/assets/**/*.*')
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(gulp.dest(output.themes))
;
};

View file

@ -0,0 +1,113 @@
/*******************************
Build Task
*******************************/
var
gulp = require('gulp'),
// node dependencies
console = require('better-console'),
fs = require('fs'),
// gulp dependencies
autoprefixer = require('gulp-autoprefixer'),
chmod = require('gulp-chmod'),
clone = require('gulp-clone'),
flatten = require('gulp-flatten'),
gulpif = require('gulp-if'),
less = require('gulp-less'),
minifyCSS = require('gulp-minify-css'),
plumber = require('gulp-plumber'),
print = require('gulp-print'),
rename = require('gulp-rename'),
replace = require('gulp-replace'),
runSequence = require('run-sequence'),
// config
config = require('../config/user'),
tasks = require('../config/tasks'),
install = require('../config/project/install'),
// shorthand
globs = config.globs,
assets = config.paths.assets,
output = config.paths.output,
source = config.paths.source,
banner = tasks.banner,
comments = tasks.regExp.comments,
log = tasks.log,
settings = tasks.settings
;
// add internal tasks (concat release)
require('../collections/internal')(gulp);
module.exports = function(callback) {
var
tasksCompleted = 0,
maybeCallback = function() {
tasksCompleted++;
if(tasksCompleted === 2) {
callback();
}
},
stream,
compressedStream,
uncompressedStream
;
console.info('Building CSS');
if( !install.isSetup() ) {
console.error('Cannot build files. Run "gulp install" to set-up Semantic');
return;
}
// unified css stream
stream = gulp.src(source.definitions + '/**/' + globs.components + '.less')
.pipe(plumber(settings.plumber.less))
.pipe(less(settings.less))
.pipe(autoprefixer(settings.prefix))
.pipe(replace(comments.variables.in, comments.variables.out))
.pipe(replace(comments.license.in, comments.license.out))
.pipe(replace(comments.large.in, comments.large.out))
.pipe(replace(comments.small.in, comments.small.out))
.pipe(replace(comments.tiny.in, comments.tiny.out))
.pipe(flatten())
;
// two concurrent streams from same source to concat release
uncompressedStream = stream.pipe(clone());
compressedStream = stream.pipe(clone());
// uncompressed component css
uncompressedStream
.pipe(plumber())
.pipe(replace(assets.source, assets.uncompressed))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(gulp.dest(output.uncompressed))
.pipe(print(log.created))
.on('end', function() {
runSequence('package uncompressed css', maybeCallback);
})
;
// compressed component css
compressedStream = stream
.pipe(plumber())
.pipe(clone())
.pipe(replace(assets.source, assets.compressed))
.pipe(minifyCSS(settings.minify))
.pipe(rename(settings.rename.minCSS))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(gulp.dest(output.compressed))
.pipe(print(log.created))
.on('end', function() {
runSequence('package compressed css', maybeCallback);
})
;
};

View file

@ -0,0 +1,77 @@
/*******************************
Build Task
*******************************/
var
gulp = require('gulp'),
// node dependencies
console = require('better-console'),
fs = require('fs'),
// gulp dependencies
chmod = require('gulp-chmod'),
flatten = require('gulp-flatten'),
gulpif = require('gulp-if'),
plumber = require('gulp-plumber'),
print = require('gulp-print'),
rename = require('gulp-rename'),
replace = require('gulp-replace'),
uglify = require('gulp-uglify'),
// config
config = require('../config/user'),
tasks = require('../config/tasks'),
install = require('../config/project/install'),
// shorthand
globs = config.globs,
assets = config.paths.assets,
output = config.paths.output,
source = config.paths.source,
banner = tasks.banner,
comments = tasks.regExp.comments,
log = tasks.log,
settings = tasks.settings
;
// add internal tasks (concat release)
require('../collections/internal')(gulp);
module.exports = function(callback) {
var
stream,
compressedStream,
uncompressedStream
;
console.info('Building Javascript');
if( !install.isSetup() ) {
console.error('Cannot build files. Run "gulp install" to set-up Semantic');
return;
}
// copy source javascript
gulp.src(source.definitions + '/**/' + globs.components + '.js')
.pipe(plumber())
.pipe(flatten())
.pipe(replace(comments.license.in, comments.license.out))
.pipe(gulp.dest(output.uncompressed))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(print(log.created))
.pipe(uglify(settings.uglify))
.pipe(rename(settings.rename.minJS))
.pipe(gulp.dest(output.compressed))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
.pipe(print(log.created))
.on('end', function() {
gulp.start('package compressed js');
gulp.start('package uncompressed js');
callback();
})
;
};

View file

@ -5,7 +5,7 @@
var
del = require('del'),
config = require('./config/user'),
tasks = require('./config/project/tasks')
tasks = require('./config/tasks')
;
// cleans distribution files

View file

@ -0,0 +1,19 @@
/*******************************
Define Sub-Tasks
*******************************/
module.exports = function(gulp) {
var
// build sub-tasks
buildJS = require('./../build/javascript'),
buildCSS = require('./../build/css'),
buildAssets = require('./../build/assets')
;
// in case these tasks are undefined during import, less make sure these are available in scope
gulp.task('build-javascript', 'Builds all javascript from source', buildJS);
gulp.task('build-css', 'Builds all css from source', buildCSS);
gulp.task('build-assets', 'Copies all assets from source', buildAssets);
};

View file

@ -16,6 +16,7 @@ module.exports = function(gulp) {
concat = require('gulp-concat'),
concatCSS = require('gulp-concat-css'),
clone = require('gulp-clone'),
dedupe = require('gulp-dedupe'),
gulpif = require('gulp-if'),
header = require('gulp-header'),
less = require('gulp-less'),
@ -31,7 +32,7 @@ module.exports = function(gulp) {
docsConfig = require('./../config/docs'),
// install config
tasks = require('./../config/project/tasks'),
tasks = require('./../config/tasks'),
release = require('./../config/project/release'),
// shorthand
@ -52,6 +53,7 @@ module.exports = function(gulp) {
gulp.task('package uncompressed css', function() {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignored + '.css')
.pipe(plumber())
.pipe(dedupe())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedCSS))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
@ -64,6 +66,7 @@ module.exports = function(gulp) {
gulp.task('package compressed css', function() {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignored + '.css')
.pipe(plumber())
.pipe(dedupe())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedMinifiedCSS))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
@ -77,6 +80,7 @@ module.exports = function(gulp) {
gulp.task('package uncompressed js', function() {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignored + '.js')
.pipe(plumber())
.pipe(dedupe())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concat(filenames.concatenatedJS))
.pipe(header(banner, settings.header))
@ -89,6 +93,7 @@ module.exports = function(gulp) {
gulp.task('package compressed js', function() {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignored + '.js')
.pipe(plumber())
.pipe(dedupe())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concat(filenames.concatenatedMinifiedJS))
.pipe(uglify(settings.concatUglify))
@ -107,6 +112,7 @@ module.exports = function(gulp) {
gulp.task('package uncompressed rtl css', function () {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignoredRTL + '.rtl.css')
.pipe(dedupe())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedRTLCSS))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
@ -118,6 +124,7 @@ module.exports = function(gulp) {
gulp.task('package compressed rtl css', function () {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignoredRTL + '.rtl.css')
.pipe(dedupe())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedMinifiedRTLCSS))
.pipe(gulpif(config.hasPermission, chmod(config.permission)))
@ -130,6 +137,7 @@ module.exports = function(gulp) {
gulp.task('package uncompressed docs css', function() {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignored + '.css')
.pipe(dedupe())
.pipe(plumber())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedCSS))
@ -141,6 +149,7 @@ module.exports = function(gulp) {
gulp.task('package compressed docs css', function() {
return gulp.src(output.uncompressed + '/**/' + globs.components + globs.ignored + '.css')
.pipe(dedupe())
.pipe(plumber())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedMinifiedCSS))
@ -164,6 +173,7 @@ module.exports = function(gulp) {
gulp.task('package uncompressed docs css', function() {
return gulp.src(docsOutput.uncompressed + '/**/' + globs.components + globs.ignored + '.css')
.pipe(dedupe())
.pipe(plumber())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedCSS))
@ -175,6 +185,7 @@ module.exports = function(gulp) {
gulp.task('package compressed docs css', function() {
return gulp.src(docsOutput.uncompressed + '/**/' + globs.components + globs.ignored + '.css')
.pipe(dedupe())
.pipe(plumber())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concatCSS(filenames.concatenatedMinifiedCSS))
@ -188,6 +199,7 @@ module.exports = function(gulp) {
gulp.task('package uncompressed docs js', function() {
return gulp.src(docsOutput.uncompressed + '/**/' + globs.components + globs.ignored + '.js')
.pipe(dedupe())
.pipe(plumber())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concat(filenames.concatenatedJS))
@ -200,6 +212,7 @@ module.exports = function(gulp) {
gulp.task('package compressed docs js', function() {
return gulp.src(docsOutput.uncompressed + '/**/' + globs.components + globs.ignored + '.js')
.pipe(dedupe())
.pipe(plumber())
.pipe(replace(assets.uncompressed, assets.packaged))
.pipe(concat(filenames.concatenatedMinifiedJS))

View file

@ -0,0 +1,16 @@
/*******************************
Define Sub-Tasks
*******************************/
module.exports = function(gulp) {
var
// rtl
buildRTL = require('./../rtl/build'),
watchRTL = require('./../rtl/watch')
;
gulp.task('watch-rtl', 'Build all files as RTL', watchRTL);
gulp.task('build-rtl', 'Watch files as RTL ', buildRTL);
};

View file

@ -4,7 +4,8 @@
*/
module.exports = {
token : 'AN-OAUTH2-TOKEN',
name : 'Your Name',
email : 'user@email.com'
token : 'AN-OAUTH2-TOKEN',
username : 'github-username',
name : 'Your Name',
email : 'user@email.com'
};

View file

@ -68,9 +68,11 @@ module.exports = {
'card',
'checkbox',
'comment',
'container',
'dimmer',
'divider',
'dropdown',
'embed',
'feed',
'flag',
'form',
@ -104,7 +106,6 @@ module.exports = {
'tab',
'table',
'transition',
'video',
'visibility'
]
};

View file

@ -4,6 +4,9 @@ This repository contains pre-compiled {component} files using the default themes
For the latest changes please see the [Release Notes](https://github.com/Semantic-Org/UI-{Component}/blob/master/RELEASE-NOTES.md)
**Special Note**
An update in `2.0.8` has fixed an issue which may have prevented some single component modules from working correctly. Please see notes in [this pull request](https://github.com/Semantic-Org/Semantic-UI/pull/2816).
If you're looking for the full version of Semantic including all components and build tools [check out the main project repository](https://github.com/Semantic-Org/Semantic-UI/tree/1.0)
#### To install with Bower

View file

@ -13,10 +13,11 @@ Package.onUse(function(api) {
api.versionsFrom('1.0');
api.use('jquery', 'client');
api.addFiles([
// icons
'themes/default/assets/fonts/icons.eot',
'themes/default/assets/fonts/icons.otf',
'themes/default/assets/fonts/icons.svg',
'themes/default/assets/fonts/icons.ttf',
'themes/default/assets/fonts/icons.woff',

View file

@ -49,6 +49,7 @@ module.exports = {
// elements
'button',
'container',
'divider',
'flag',
'header',
@ -84,6 +85,7 @@ module.exports = {
'checkbox',
'dimmer',
'dropdown',
'embed',
'modal',
'nag',
'popup',
@ -95,7 +97,6 @@ module.exports = {
'sticky',
'tab',
'transition',
'video',
// behaviors
'api',

View file

@ -5,7 +5,11 @@
/* Paths used for "serve-docs" and "build-docs" tasks */
module.exports = {
base: '',
globs: {
eco: '**/*.html.eco'
},
paths: {
clean: '../docs/out/dist/',
source: {
config : 'src/theme.config',
definitions : 'src/definitions/',
@ -13,12 +17,16 @@ module.exports = {
themes : 'src/themes/'
},
output: {
examples : '../docs/out/examples/',
less : '../docs/out/src/',
metadata : '../docs/out/',
packaged : '../docs/out/dist/',
uncompressed : '../docs/out/dist/components/',
compressed : '../docs/out/dist/components/',
themes : '../docs/out/dist/themes/'
},
clean: '../docs/out/dist/'
template: {
eco: '../docs/server/documents/'
},
}
};
};

View file

@ -3,36 +3,48 @@
*******************************/
var
gulp = require('gulp-help')(require('gulp')),
gulp = require('gulp-help')(require('gulp')),
// read user config to know what task to load
config = require('./tasks/config/user'),
config = require('./tasks/config/user'),
// import tasks
build = require('./tasks/build'),
clean = require('./tasks/clean'),
version = require('./tasks/version'),
watch = require('./tasks/watch'),
// watch changes
watch = require('./tasks/watch'),
// build all files
build = require('./tasks/build'),
buildJS = require('./tasks/build/javascript'),
buildCSS = require('./tasks/build/css'),
buildAssets = require('./tasks/build/assets'),
// utility
clean = require('./tasks/clean'),
version = require('./tasks/version'),
// docs tasks
serveDocs = require('./tasks/docs/serve'),
buildDocs = require('./tasks/docs/build'),
serveDocs = require('./tasks/docs/serve'),
buildDocs = require('./tasks/docs/build'),
// rtl
buildRTL = require('./tasks/rtl/build'),
watchRTL = require('./tasks/rtl/watch')
buildRTL = require('./tasks/rtl/build'),
watchRTL = require('./tasks/rtl/watch')
;
/*--------------
Common
---------------*/
/*******************************
Tasks
*******************************/
gulp.task('default', false, [
'watch'
]);
gulp.task('watch', 'Watch for site/theme changes', watch);
gulp.task('build', 'Builds all files from source', build);
gulp.task('build-javascript', 'Builds all javascript from source', buildJS);
gulp.task('build-css', 'Builds all css from source', buildCSS);
gulp.task('build-assets', 'Copies all assets from source', buildAssets);
gulp.task('clean', 'Clean dist folder', clean);
gulp.task('version', 'Displays current version of Semantic', version);
@ -42,13 +54,14 @@ gulp.task('version', 'Displays current version of Semantic', version);
---------------*/
/*
See usage instruction in Docs Readme
Lets you serve files to a local documentation instance
https://github.com/Semantic-Org/Semantic-UI-Docs/
*/
gulp.task('serve-docs', 'Serve file changes to SUI Docs', serveDocs);
gulp.task('build-docs', 'Build all files and add to SUI Docs', buildDocs);
/*--------------
RTL
---------------*/
@ -56,4 +69,4 @@ gulp.task('build-docs', 'Build all files and add to SUI Docs', buildDocs);
if(config.rtl) {
gulp.task('watch-rtl', 'Build all files as RTL', watchRTL);
gulp.task('build-rtl', 'Watch files as RTL ', buildRTL);
}
}

View file

@ -119,6 +119,13 @@ module.exports = {
config.globs = {};
}
// remove duplicates from component array
if(config.components instanceof Array) {
config.components = config.components.filter(function(component, index) {
return config.components.indexOf(component) == index;
});
}
// takes component object and creates file glob matching selected components
config.globs.components = (typeof config.components == 'object')
? (config.components.length > 1)

View file

@ -92,7 +92,6 @@ module.exports = {
folder = pathArray[pathArray.length - 1],
nextDirectory = path.join(directory, path.sep, '..')
;
console.log(folder, nextDirectory);
if( folder == 'bower_components') {
return {
name: 'Bower',
@ -228,7 +227,7 @@ module.exports = {
siteVariable: /@siteFolder .*\'(.*)/mg
},
// source paths (relative to tasks/install.js )
// source paths (when installing)
source: {
config : './semantic.json.example',
definitions : './src/definitions',
@ -239,6 +238,7 @@ module.exports = {
themeConfig : './src/theme.config.example',
themeImport : './src/theme.less',
themes : './src/themes',
defaultTheme : './src/themes/default',
userGulpFile : './tasks/config/npm/gulpfile.js'
},
@ -253,15 +253,17 @@ module.exports = {
// folder paths to files relative to root
folders: {
config : './',
definitions : 'src/definitions/',
lessImport : 'src/',
modules : 'node_modules/',
site : 'src/site/',
tasks : 'tasks/',
themeConfig : 'src/',
themeImport : 'src/',
themes : 'src/themes/'
config : './',
definitions : 'src/definitions/',
lessImport : 'src/',
modules : 'node_modules/',
site : 'src/site/',
tasks : 'tasks/',
themeConfig : 'src/',
themeImport : 'src/',
themes : 'src/themes/',
defaultTheme : 'default/' // only path that is relative to another directory and not root
},
// questions asked during install
@ -276,7 +278,7 @@ module.exports = {
' {packageMessage} \n' +
' \n' +
' Is this your project folder?\n' +
' \033[92m{root}\033[0m \n' +
' \x1b[92m{root}\x1b[0m \n' +
' \n ' +
'\n',
choices: [
@ -352,6 +354,7 @@ module.exports = {
{ name: "reset", checked: true },
{ name: "site", checked: true },
{ name: "button", checked: true },
{ name: "container", checked: true },
{ name: "divider", checked: true },
{ name: "flag", checked: true },
{ name: "header", checked: true },
@ -381,6 +384,7 @@ module.exports = {
{ name: "checkbox", checked: true },
{ name: "dimmer", checked: true },
{ name: "dropdown", checked: true },
{ name: "embed", checked: true },
{ name: "modal", checked: true },
{ name: "nag", checked: true },
{ name: "popup", checked: true },
@ -392,7 +396,6 @@ module.exports = {
{ name: "sticky", checked: true },
{ name: "tab", checked: true },
{ name: "transition", checked: true },
{ name: "video", checked: true },
{ name: "api", checked: true },
{ name: "form", checked: true },
{ name: "state", checked: true },
@ -437,6 +440,10 @@ module.exports = {
name: 'Yes',
value: true
},
{
name: 'Build Both',
value: 'both'
}
]
},
{
@ -729,33 +736,20 @@ module.exports = {
/* Copy Install Folders */
wrench: {
// copy during npm update (default theme / definition)
update: {
// overwrite existing files update & install (default theme / definition)
overwrite: {
forceDelete : true,
excludeHiddenUnix : true,
preserveFiles : false
},
// copy during first npm install
install: {
forceDelete : true,
excludeHiddenUnix : true,
preserveFiles : false
},
// copy for node_modules
modules: {
forceDelete : true,
excludeHiddenUnix : true,
preserveFiles : false
},
// copy for site theme
site: {
// only create files that don't exist (site theme update)
merge: {
forceDelete : false,
excludeHiddenUnix : true,
preserveFiles : true
}
}
}

View file

@ -5,7 +5,7 @@
var
requireDotFile = require('require-dot-file'),
config,
package,
npmPackage,
version
;
@ -15,25 +15,29 @@ var
*******************************/
try {
config = requireDotFile('semantic.json');
package = require('../../../package.json');
// looks for version in config or package.json (whichever is available)
version = (config && config.version !== undefined)
? config.version
: package.version
;
config = requireDotFile('semantic.json');
}
catch(error) {}
try {
npmPackage = require('../../../package.json');
}
catch(error) {
// generate fake package
package = {
npmPackage = {
name: 'Unknown',
version: 'x.x'
};
}
// looks for version in config or package.json (whichever is available)
version = (npmPackage && npmPackage.version !== undefined && npmPackage.name == 'semantic-ui')
? npmPackage.version
: config.version
;
/*******************************
Export
*******************************/
@ -56,6 +60,6 @@ module.exports = {
+ ' *' + '\n'
+ ' */' + '\n',
version : package.version
version : version
};

View file

@ -1,6 +1,7 @@
var
config = require('../user'),
release = require('./release')
console = require('better-console'),
config = require('./user'),
release = require('./project/release')
;
@ -57,7 +58,7 @@ module.exports = {
}
},
theme: /.*\/themes\/.*?(?=\/)/mg
theme: /.*(\/|\\)themes(\/|\\).*?(?=(\/|\\))/mg
},
@ -76,14 +77,46 @@ module.exports = {
url : release.url
},
plumber: {
less: {
errorHandler: function(error) {
var
regExp = {
variable : /@(\S.*?)\s/,
theme : /themes[\/\\]+(.*?)[\/\\].*/,
element : /[\/\\]([^\/\\*]*)\.overrides/
},
theme,
element
;
if(error.filename.match(/theme.less/)) {
if(error.line == 5) {
element = regExp.variable.exec(error.message)[1];
if(element) {
console.error('Missing theme.config value for ', element);
}
console.error('Most likely new UI was added in an update. You will need to add missing elements from theme.config.example');
}
if(error.line == 46) {
element = regExp.element.exec(error.message)[1];
theme = regExp.theme.exec(error.message)[1];
console.error(theme + ' is not an available theme for ' + element);
}
}
else {
console.log(error);
}
this.emit('end');
}
}
},
/* What Browsers to Prefix */
prefix: {
browsers: [
'last 2 version',
'last 2 versions',
'> 1%',
'opera 12.1',
'safari 6',
'ie 9',
'bb 10',
'android 4'
]
@ -124,4 +157,4 @@ module.exports = {
}
}
};
};

View file

@ -8,6 +8,7 @@ var
// node dependencies
console = require('better-console'),
fs = require('fs'),
map = require('map-stream'),
// gulp dependencies
autoprefixer = require('gulp-autoprefixer'),
@ -28,10 +29,13 @@ var
config = require('../config/docs'),
// install config
tasks = require('../config/tasks'),
configSetup = require('../config/project/config'),
tasks = require('../config/project/tasks'),
install = require('../config/project/install'),
// metadata parsing
metadata = require('./metadata'),
// shorthand
globs,
assets,
@ -64,17 +68,44 @@ module.exports = function(callback) {
output = config.paths.output;
source = config.paths.source;
/*--------------
Parse metadata
---------------*/
// parse all *.html.eco in docs repo, data will end up in
// metadata.result object. Note this assumes that the docs
// repository is present and in proper directory location as
// specified by docs.json.
console.info('Building Metadata');
gulp.src(config.paths.template.eco + globs.eco)
.pipe(map(metadata.parser))
.on('end', function() {
fs.writeFile(output.metadata + '/metadata.json', JSON.stringify(metadata.result, null, 2));
})
;
/*--------------
Copy Examples
---------------*/
console.info('Copying examples');
// copy src/ to server
gulp.src('examples/**/*.*')
.pipe(gulp.dest(output.examples))
.pipe(print(log.created))
;
/*--------------
Copy Source
---------------*/
console.info('Copying LESS source');
// copy src/ to server
gulp.src('src/**/*.*')
.pipe(gulp.dest(output.less))
.pipe(print(log.created))
;
/*--------------
Build
---------------*/
@ -155,4 +186,4 @@ module.exports = function(callback) {
})
;
};
};

View file

@ -0,0 +1,138 @@
/*******************************
Summarize Docs
*******************************/
var
// node dependencies
console = require('better-console'),
fs = require('fs'),
YAML = require('yamljs')
;
var data = {};
/**
* Test for prefix in string.
* @param {string} str
* @param {string} prefix
* @return {boolean}
*/
function startsWith(str, prefix) {
return str.indexOf(prefix) === 0;
};
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
/**
* Parses a file for metadata and stores result in data object.
* @param {File} file - object provided by map-stream.
* @param {function(?,File)} - callback provided by map-stream to
* reply when done.
*/
function parser(file, callback) {
// file exit conditions
if(file.isNull()) {
return callback(null, file); // pass along
}
if(file.isStream()) {
return callback(new Error('Streaming not supported'));
}
try {
var
/** @type {string} */
text = String(file.contents.toString('utf8')),
lines = text.split('\n'),
filename = file.path.substring(0, file.path.length - 4),
key = 'server/documents',
position = filename.indexOf(key)
;
// exit conditions
if(!lines) {
return;
}
if(position < 0) {
return callback(null, file);
}
filename = filename.substring(position + key.length + 1, filename.length);
var
lineCount = lines.length,
active = false,
yaml = [],
categories = [
'UI Element',
'UI Global',
'UI Collection',
'UI View',
'UI Module',
'UI Behavior'
],
index,
meta,
line
;
for(index = 0; index < lineCount; index++) {
line = lines[index];
// Wait for metadata block to begin
if(!active) {
if(startsWith(line, '---')) {
active = true;
}
continue;
}
// End of metadata block, stop parsing.
if(startsWith(line, '---')) {
break;
}
yaml.push(line);
}
// Parse yaml.
meta = YAML.parse(yaml.join('\n'));
if(meta && meta.type && meta.title && inArray(meta.type, categories) ) {
meta.category = meta.type;
meta.filename = filename;
meta.url = '/' + filename;
meta.title = meta.title;
// Primary key will by filepath
data[meta.element] = meta;
}
else {
// skip
// console.log(meta);
}
}
catch(error) {
console.log(error, filename);
}
callback(null, file);
}
/**
* Export function expected by map-stream.
*/
module.exports = {
result : data,
parser : parser
};

View file

@ -28,8 +28,8 @@ var
config = require('../config/docs'),
// task config
tasks = require('../config/tasks'),
configSetup = require('../config/project/config'),
tasks = require('../config/project/tasks'),
install = require('../config/project/install'),
// shorthand
@ -76,6 +76,24 @@ module.exports = function () {
})
;
/*--------------
Copy Examples
---------------*/
gulp
.watch([
'examples/**/*.*'
], function(file) {
console.clear();
return gulp.src(file.path, {
base: 'examples/'
})
.pipe(gulp.dest(output.examples))
.pipe(print(log.created))
;
})
;
/*--------------
Watch CSS
---------------*/
@ -111,14 +129,15 @@ module.exports = function () {
---------------*/
// recompile on *.override , *.variable change
isConfig = (file.path.indexOf('theme.config') !== -1);
isConfig = (file.path.indexOf('theme.config') !== -1 || file.path.indexOf('site.variables') !== -1);
isPackagedTheme = (file.path.indexOf(source.themes) !== -1);
isSiteTheme = (file.path.indexOf(source.site) !== -1);
isDefinition = (file.path.indexOf(source.definitions) !== -1);
if(isConfig) {
console.info('Change detected in theme config, rebuild docs with `build-docs`');
// impossible to tell which file was updated in theme.config
// console.info('Rebuilding all files');
// cant rebuild paths are wrong
// gulp.start('build-docs');
return;
}
else if(isPackagedTheme) {

View file

@ -23,6 +23,7 @@ var
fs = require('fs'),
mkdirp = require('mkdirp'),
path = require('path'),
runSequence = require('run-sequence'),
// gulp dependencies
chmod = require('gulp-chmod'),
@ -54,329 +55,367 @@ var
;
// Export install task
module.exports = function () {
module.exports = function (callback) {
var
currentConfig = requireDotFile('semantic.json'),
manager = install.getPackageManager(),
rootQuestions = questions.root,
installFolder = false,
answers
;
console.clear();
/* Test NPM install
manager = {
name : 'NPM',
root : path.normalize(__dirname + '/../')
};
*/
/* Don't do end user config if SUI is a sub-module */
if( install.isSubModule() ) {
console.info('SUI is a sub-module, skipping end-user install');
return;
}
/*-----------------
Update SUI
-----------------*/
// run update scripts if semantic.json exists
if(currentConfig && manager.name === 'NPM') {
var
currentConfig = requireDotFile('semantic.json'),
manager = install.getPackageManager(),
rootQuestions = questions.root
updateFolder = path.join(manager.root, currentConfig.base),
updatePaths = {
config : path.join(manager.root, files.config),
tasks : path.join(updateFolder, folders.tasks),
themeImport : path.join(updateFolder, folders.themeImport),
definition : path.join(currentConfig.paths.source.definitions),
site : path.join(currentConfig.paths.source.site),
theme : path.join(currentConfig.paths.source.themes),
defaultTheme : path.join(currentConfig.paths.source.themes, folders.defaultTheme)
}
;
console.clear();
// duck-type if there is a project installed
if( fs.existsSync(updatePaths.definition) ) {
/* Test NPM
manager = {
name : 'NPM',
root : path.normalize(__dirname + '/../')
};
*/
// perform update if new version
if(currentConfig.version !== release.version) {
console.log('Updating Semantic UI from ' + currentConfig.version + ' to ' + release.version);
/*--------------
PM Config
---------------*/
console.info('Updating ui definitions...');
wrench.copyDirSyncRecursive(source.definitions, updatePaths.definition, settings.wrench.overwrite);
/* Don't do end user config if SUI is a sub-module */
if( install.isSubModule() ) {
console.info('SUI is a sub-module, skipping end-user install');
return;
}
console.info('Updating default theme...');
wrench.copyDirSyncRecursive(source.themes, updatePaths.theme, settings.wrench.merge);
wrench.copyDirSyncRecursive(source.defaultTheme, updatePaths.defaultTheme, settings.wrench.overwrite);
// run update scripts if semantic.json exists
if(currentConfig && manager.name === 'NPM') {
console.info('Updating tasks...');
wrench.copyDirSyncRecursive(source.tasks, updatePaths.tasks, settings.wrench.overwrite);
var
updateFolder = path.join(manager.root, currentConfig.base),
updatePaths = {
config : path.join(manager.root, files.config),
tasks : path.join(updateFolder, folders.tasks),
themeImport : path.join(updateFolder, folders.themeImport),
definition : path.join(currentConfig.paths.source.definitions),
site : path.join(currentConfig.paths.source.site),
theme : path.join(currentConfig.paths.source.themes)
}
;
console.info('Updating gulpfile.js');
gulp.src(source.userGulpFile)
.pipe(plumber())
.pipe(gulp.dest(updateFolder))
;
// duck-type if there is a project installed
if( fs.existsSync(updatePaths.definition) ) {
// copy theme import
console.info('Updating theme import file');
gulp.src(source.themeImport)
.pipe(plumber())
.pipe(gulp.dest(updatePaths.themeImport))
;
// perform update if new version
if(currentConfig.version !== release.version) {
console.log('Updating Semantic UI from ' + currentConfig.version + ' to ' + release.version);
console.info('Adding new site theme files...');
wrench.copyDirSyncRecursive(source.site, updatePaths.site, settings.wrench.merge);
console.info('Updating ui definitions...');
wrench.copyDirSyncRecursive(source.definitions, updatePaths.definition, settings.wrench.update);
console.info('Updating version...');
console.info('Updating default theme...');
wrench.copyDirSyncRecursive(source.themes, updatePaths.theme, settings.wrench.update);
// update version number in semantic.json
gulp.src(updatePaths.config)
.pipe(plumber())
.pipe(rename(settings.rename.json)) // preserve file extension
.pipe(jsonEditor({
version: release.version
}))
.pipe(gulp.dest(manager.root))
;
console.info('Updating tasks...');
wrench.copyDirSyncRecursive(source.tasks, updatePaths.tasks, settings.wrench.update);
console.info('Updating gulpfile.js');
gulp.src(source.userGulpFile)
.pipe(plumber())
.pipe(gulp.dest(updateFolder))
;
// copy theme import
console.info('Updating theme import file');
gulp.src(source.themeImport)
.pipe(plumber())
.pipe(gulp.dest(updatePaths.themeImport))
;
console.info('Adding new site theme files...');
wrench.copyDirSyncRecursive(source.site, updatePaths.site, settings.wrench.site);
console.info('Updating version...');
// update version number in semantic.json
gulp.src(updatePaths.config)
.pipe(plumber())
.pipe(rename(settings.rename.json)) // preserve file extension
.pipe(jsonEditor({
version: release.version
}))
.pipe(gulp.dest(manager.root))
;
console.info('Update complete! Run "\033[92mgulp build\033[0m" to rebuild dist/ files.');
return;
}
else {
console.log('Current version of Semantic UI already installed');
return;
}
console.info('Update complete! Run "\x1b[92mgulp build\x1b[0m" to rebuild dist/ files.');
return;
}
else {
console.error('Cannot locate files to update at path: ', updatePaths.definition);
console.log('Running installer');
console.log('Current version of Semantic UI already installed');
return;
}
}
/*--------------
Determine Root
---------------*/
// PM that supports Build Tools (NPM Only Now)
if(manager.name == 'NPM') {
rootQuestions[0].message = rootQuestions[0].message
.replace('{packageMessage}', 'We detected you are using \033[92m' + manager.name + '\033[0m. Nice! ')
.replace('{root}', manager.root)
;
// set default path to detected PM root
rootQuestions[0].default = manager.root;
rootQuestions[1].default = manager.root;
// insert PM questions after "Install Type" question
Array.prototype.splice.apply(questions.setup, [2, 0].concat(rootQuestions));
// omit cleanup questions for managed install
questions.cleanup = [];
else {
console.error('Cannot locate files to update at path: ', updatePaths.definition);
console.log('Running installer');
}
/*--------------
Set-up
---------------*/
}
/*--------------
Determine Root
---------------*/
// PM that supports Build Tools (NPM Only Now)
if(manager.name == 'NPM') {
rootQuestions[0].message = rootQuestions[0].message
.replace('{packageMessage}', 'We detected you are using \x1b[92m' + manager.name + '\x1b[0m. Nice! ')
.replace('{root}', manager.root)
;
// set default path to detected PM root
rootQuestions[0].default = manager.root;
rootQuestions[1].default = manager.root;
// insert PM questions after "Install Type" question
Array.prototype.splice.apply(questions.setup, [2, 0].concat(rootQuestions));
// omit cleanup questions for managed install
questions.cleanup = [];
}
/*--------------
Create SUI
---------------*/
gulp.task('run setup', function() {
return gulp
.src('gulpfile.js')
.pipe(prompt.prompt(questions.setup, function(answers) {
.pipe(prompt.prompt(questions.setup, function(setupAnswers) {
// hoist
answers = setupAnswers;
}))
;
/*--------------
Exit Conditions
---------------*/
});
// if config exists and user specifies not to proceed
if(answers.overwrite !== undefined && answers.overwrite == 'no') {
gulp.task('create install files', function(callback) {
/*--------------
Exit Conditions
---------------*/
// if config exists and user specifies not to proceed
if(answers.overwrite !== undefined && answers.overwrite == 'no') {
return;
}
console.clear();
console.log('Installing');
console.log('------------------------------');
/*--------------
Paths
---------------*/
var
installPaths = {
config : files.config,
configFolder : folders.config,
site : answers.site || folders.site,
themeConfig : files.themeConfig,
themeConfigFolder : folders.themeConfig
}
;
/*--------------
NPM Install
---------------*/
// Check if PM install
if(answers.useRoot || answers.customRoot) {
// Set root to custom root path if set
if(answers.customRoot) {
if(answers.customRoot === '') {
console.log('Unable to proceed, invalid project root');
return;
}
manager.root = answers.customRoot;
}
console.clear();
console.log('Installing');
console.log('------------------------------');
// special install paths only for PM install
installPaths = extend(false, {}, installPaths, {
definition : folders.definitions,
lessImport : folders.lessImport,
tasks : folders.tasks,
theme : folders.themes,
defaultTheme : path.join(folders.themes, folders.defaultTheme),
themeImport : folders.themeImport
});
// add project root to semantic root
installFolder = path.join(manager.root, answers.semanticRoot);
// add install folder to all output paths
for(var destination in installPaths) {
if( installPaths.hasOwnProperty(destination) ) {
// config goes in project root, rest in install folder
installPaths[destination] = (destination == 'config' || destination == 'configFolder')
? path.normalize( path.join(manager.root, installPaths[destination]) )
: path.normalize( path.join(installFolder, installPaths[destination]) )
;
}
}
// create project folders
try {
mkdirp.sync(installFolder);
mkdirp.sync(installPaths.definition);
mkdirp.sync(installPaths.theme);
mkdirp.sync(installPaths.tasks);
}
catch(error) {
console.error('NPM does not have permissions to create folders at your specified path. Adjust your folders permissions and run "npm install" again');
}
console.log('Installing to \x1b[92m' + answers.semanticRoot + '\x1b[0m');
console.info('Copying UI definitions');
wrench.copyDirSyncRecursive(source.definitions, installPaths.definition, settings.wrench.overwrite);
console.info('Copying UI themes');
wrench.copyDirSyncRecursive(source.themes, installPaths.theme, settings.wrench.merge);
wrench.copyDirSyncRecursive(source.defaultTheme, installPaths.defaultTheme, settings.wrench.overwrite);
console.info('Copying gulp tasks');
wrench.copyDirSyncRecursive(source.tasks, installPaths.tasks, settings.wrench.overwrite);
// copy theme import
console.info('Adding theme files');
gulp.src(source.themeImport)
.pipe(plumber())
.pipe(gulp.dest(installPaths.themeImport))
;
gulp.src(source.lessImport)
.pipe(plumber())
.pipe(gulp.dest(installPaths.lessImport))
;
// create gulp file
console.info('Creating gulpfile.js');
gulp.src(source.userGulpFile)
.pipe(plumber())
.pipe(gulp.dest(installFolder))
;
}
/*--------------
Paths
---------------*/
/*--------------
Site Theme
---------------*/
var
installPaths = {
config : files.config,
configFolder : folders.config,
site : answers.site || folders.site,
themeConfig : files.themeConfig,
themeConfigFolder : folders.themeConfig
},
installFolder = false
// Copy _site templates folder to destination
if( fs.existsSync(installPaths.site) ) {
console.info('Site folder exists, merging files (no overwrite)', installPaths.site);
}
else {
console.info('Creating site theme folder', installPaths.site);
}
wrench.copyDirSyncRecursive(source.site, installPaths.site, settings.wrench.merge);
/*--------------
Theme Config
---------------*/
gulp.task('create theme.config', function() {
var
// determine path to site theme folder from theme config
// force CSS path variable to use forward slashes for paths
pathToSite = path.relative(path.resolve(installPaths.themeConfigFolder), path.resolve(installPaths.site)).replace(/\\/g,'/'),
siteVariable = "@siteFolder : '" + pathToSite + "/';"
;
// rewrite site variable in theme.less
console.info('Adjusting @siteFolder to: ', pathToSite + '/');
if(fs.existsSync(installPaths.themeConfig)) {
console.info('Modifying src/theme.config (LESS config)', installPaths.themeConfig);
return gulp.src(installPaths.themeConfig)
.pipe(plumber())
.pipe(replace(regExp.siteVariable, siteVariable))
.pipe(gulp.dest(installPaths.themeConfigFolder))
;
/*--------------
PM Install
---------------*/
// Check if PM install
if(answers.useRoot || answers.customRoot) {
// Set root to custom root path if set
if(answers.customRoot) {
if(answers.customRoot === '') {
console.log('Unable to proceed, invalid project root');
return;
}
manager.root = answers.customRoot;
}
// special install paths only for PM install
installPaths = extend(false, {}, installPaths, {
definition : folders.definitions,
lessImport : folders.lessImport,
tasks : folders.tasks,
theme : folders.themes,
themeImport : folders.themeImport
});
// add project root to semantic root
installFolder = path.join(manager.root, answers.semanticRoot);
// add install folder to all output paths
for(var destination in installPaths) {
if( installPaths.hasOwnProperty(destination) ) {
// config goes in project root, rest in install folder
installPaths[destination] = (destination == 'config' || destination == 'configFolder')
? path.normalize( path.join(manager.root, installPaths[destination]) )
: path.normalize( path.join(installFolder, installPaths[destination]) )
;
}
}
// create project folders
try {
mkdirp.sync(installFolder);
mkdirp.sync(installPaths.definition);
mkdirp.sync(installPaths.theme);
mkdirp.sync(installPaths.tasks);
}
catch(error) {
console.error('NPM does not have permissions to create folders at your specified path. Adjust your folders permissions and run "npm install" again');
}
console.log('Installing to \033[92m' + answers.semanticRoot + '\033[0m');
console.info('Copying UI definitions');
wrench.copyDirSyncRecursive(source.definitions, installPaths.definition, settings.wrench.install);
wrench.copyDirSyncRecursive(source.themes, installPaths.theme, settings.wrench.install);
console.info('Copying gulp tasks');
wrench.copyDirSyncRecursive(source.tasks, installPaths.tasks, settings.wrench.install);
// copy theme import
console.info('Adding theme files');
gulp.src(source.themeImport)
.pipe(plumber())
.pipe(gulp.dest(installPaths.themeImport))
;
gulp.src(source.lessImport)
.pipe(plumber())
.pipe(gulp.dest(installPaths.lessImport))
;
// create gulp file
console.info('Creating gulpfile.js');
gulp.src(source.userGulpFile)
.pipe(plumber())
.pipe(gulp.dest(installFolder))
;
}
/*--------------
Site Theme
---------------*/
// Copy _site templates folder to destination
if( fs.existsSync(installPaths.site) ) {
console.info('Site folder exists, merging files (no overwrite)', installPaths.site);
}
else {
console.info('Creating site theme folder', installPaths.site);
}
wrench.copyDirSyncRecursive(source.site, installPaths.site, settings.wrench.site);
/*--------------
Theme Config
---------------*/
var
// determine path to site theme folder from theme config
// force CSS path variable to use forward slashes for paths
pathToSite = path.relative(path.resolve(installPaths.themeConfigFolder), path.resolve(installPaths.site)).replace(/\\/g,'/'),
siteVariable = "@siteFolder : '" + pathToSite + "/';"
}
else {
console.info('Creating src/theme.config (LESS config)', installPaths.themeConfig);
return gulp.src(source.themeConfig)
.pipe(plumber())
.pipe(rename({ extname : '' }))
.pipe(replace(regExp.siteVariable, siteVariable))
.pipe(gulp.dest(installPaths.themeConfigFolder))
;
}
});
// rewrite site variable in theme.less
console.info('Adjusting @siteFolder to: ', pathToSite + '/');
/*--------------
Semantic.json
---------------*/
if(fs.existsSync(installPaths.themeConfig)) {
console.info('Modifying src/theme.config (LESS config)', installPaths.themeConfig);
gulp.src(installPaths.themeConfig)
.pipe(plumber())
.pipe(replace(regExp.siteVariable, siteVariable))
.pipe(gulp.dest(installPaths.themeConfigFolder))
;
}
else {
console.info('Creating src/theme.config (LESS config)', installPaths.themeConfig);
gulp.src(source.themeConfig)
.pipe(plumber())
.pipe(rename({ extname : '' }))
.pipe(replace(regExp.siteVariable, siteVariable))
.pipe(gulp.dest(installPaths.themeConfigFolder))
;
}
gulp.task('create semantic.json', function() {
/*--------------
Semantic.json
---------------*/
var
jsonConfig = install.createJSON(answers)
;
var
jsonConfig = install.createJSON(answers)
// adjust variables in theme.less
if( fs.existsSync(files.config) ) {
console.info('Extending config file (semantic.json)', installPaths.config);
return gulp.src(installPaths.config)
.pipe(plumber())
.pipe(rename(settings.rename.json)) // preserve file extension
.pipe(jsonEditor(jsonConfig))
.pipe(gulp.dest(installPaths.configFolder))
;
}
else {
console.info('Creating config file (semantic.json)', installPaths.config);
return gulp.src(source.config)
.pipe(plumber())
.pipe(rename({ extname : '' })) // remove .template from ext
.pipe(jsonEditor(jsonConfig))
.pipe(gulp.dest(installPaths.configFolder))
;
}
// adjust variables in theme.less
if( fs.existsSync(files.config) ) {
console.info('Extending config file (semantic.json)', installPaths.config);
gulp.src(installPaths.config)
.pipe(plumber())
.pipe(rename(settings.rename.json)) // preserve file extension
.pipe(jsonEditor(jsonConfig))
.pipe(gulp.dest(installPaths.configFolder))
;
}
else {
console.info('Creating config file (semantic.json)', installPaths.config);
gulp.src(source.config)
.pipe(plumber())
.pipe(rename({ extname : '' })) // remove .template from ext
.pipe(jsonEditor(jsonConfig))
.pipe(gulp.dest(installPaths.configFolder))
;
}
});
// Completion Message
if(installFolder) {
console.log('Install complete! Navigate to \033[92m' + answers.semanticRoot + '\033[0m and run "\033[92mgulp build\033[0m" to build');
}
else {
console.log('');
console.log('');
}
runSequence(
'create theme.config',
'create semantic.json',
callback
);
}))
});
gulp.task('clean up install', function() {
// Completion Message
if(installFolder) {
console.log('\n Setup Complete! \n Installing Peer Dependencies. \x1b[0;31mPlease refrain from ctrl + c\x1b[0m... \n After completion navigate to \x1b[92m' + answers.semanticRoot + '\x1b[0m and run "\x1b[92mgulp build\x1b[0m" to build');
process.exit(0);
}
else {
console.log('');
console.log('');
}
return gulp
.src('gulpfile.js')
.pipe(prompt.prompt(questions.cleanup, function(answers) {
if(answers.cleanup == 'yes') {
del(install.setupFiles);
@ -386,6 +425,13 @@ module.exports = function () {
}
}))
;
});
runSequence(
'run setup',
'create install files',
'clean up install',
callback
);
};

View file

@ -27,7 +27,7 @@ var
config = require('../config/user'),
// install config
tasks = require('../config/project/tasks'),
tasks = require('../config/tasks'),
install = require('../config/project/install'),
// shorthand

View file

@ -29,7 +29,7 @@ var
config = require('../config/user'),
// task config
tasks = require('../config/project/tasks'),
tasks = require('../config/tasks'),
install = require('../config/project/install'),
// shorthand

View file

@ -3,7 +3,7 @@
*******************************/
var
gulp = require('gulp'),
gulp = require('gulp-help')(require('gulp')),
// node dependencies
console = require('better-console'),
@ -28,7 +28,7 @@ var
config = require('./config/user'),
// task config
tasks = require('./config/project/tasks'),
tasks = require('./config/tasks'),
install = require('./config/project/install'),
// shorthand
@ -44,7 +44,10 @@ var
;
// add tasks that shouldn't be exposed to end-user
// add tasks referenced using gulp.run (sub-tasks)
if(config.rtl) {
require('./collections/rtl')(gulp);
}
require('./collections/internal')(gulp);
@ -56,7 +59,10 @@ module.exports = function(callback) {
return;
}
// check for right-to-left language
// check for right-to-left (RTL) language
if(config.rtl == 'both') {
gulp.start('watch-rtl');
}
if(config.rtl === true || config.rtl === 'Yes') {
gulp.start('watch-rtl');
return;
@ -100,15 +106,15 @@ module.exports = function(callback) {
---------------*/
// recompile on *.override , *.variable change
isConfig = (file.path.indexOf('theme.config') !== -1);
isConfig = (file.path.indexOf('theme.config') !== -1 || file.path.indexOf('site.variables') !== -1);
isPackagedTheme = (file.path.indexOf(source.themes) !== -1);
isSiteTheme = (file.path.indexOf(source.site) !== -1);
isDefinition = (file.path.indexOf(source.definitions) !== -1);
if(isConfig) {
console.info('Change detected in theme config');
console.info('Rebuilding all UI');
// impossible to tell which file was updated in theme.config, rebuild all
gulp.start('build');
gulp.start('build-css');
return;
}
else if(isPackagedTheme) {
@ -134,8 +140,9 @@ module.exports = function(callback) {
// unified css stream
stream = gulp.src(lessPath)
.pipe(plumber())
.pipe(plumber(settings.plumber.less))
.pipe(less(settings.less))
.pipe(print(log.created))
.pipe(replace(comments.variables.in, comments.variables.out))
.pipe(replace(comments.license.in, comments.license.out))
.pipe(replace(comments.large.in, comments.large.out))
@ -170,7 +177,6 @@ module.exports = function(callback) {
gulp.start('package compressed css');
})
;
}
else {
console.log('Cannot find UI definition at path', lessPath);
@ -211,7 +217,7 @@ module.exports = function(callback) {
// only copy assets that match component names (or their plural)
gulp
.watch([
source.themes + '/**/assets/**/' + globs.components + '?(s).*'
source.themes + '/**/assets/**/*.*'
], function(file) {
// copy assets
gulp.src(file.path, { base: source.themes })