diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 4492916f1..c5e1f61f6 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,15 @@ ## RELEASE NOTES +### Version 1.9.3 - February 20, 2015 + +**Bugs** +- **Tab** - Fixed bug when loading `remote` content with `tab` where current tab would not hide while loading +- **Tab** - Tab with remote content and `auto: true` now removes duplicate slashes from url path +- **API** - Simplified `api` debug output to console to more clearly label url and data sent + +**Docs** +- **Tab** - Added new tab remote content example with stubbed AJAX using SinonJS + ### Version 1.9.2 - February 19, 2015 Added new repositories for css and less only versions, can be installed with diff --git a/package.json b/package.json index 12a9d94a3..90a893d8a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name" : "semantic-ui", - "version" : "1.9.2", + "version" : "1.9.3", "title" : "Semantic UI", "description" : "Semantic empowers designers and developers by creating a shared vocabulary for UI.", "homepage" : "http://www.semantic-ui.com", diff --git a/src/definitions/behaviors/api.js b/src/definitions/behaviors/api.js index 71eaef292..557c77849 100644 --- a/src/definitions/behaviors/api.js +++ b/src/definitions/behaviors/api.js @@ -180,7 +180,9 @@ $.api = $.fn.api = function(parameters) { complete : function() {} }); - module.verbose('Creating AJAX request with settings', ajaxSettings); + module.debug('Querying URL', ajaxSettings.url); + module.debug('Sending data', data, ajaxSettings.method); + module.verbose('Using AJAX settings', ajaxSettings); if( module.is.loading() ) { // throttle additional requests @@ -383,7 +385,7 @@ $.api = $.fn.api = function(parameters) { // if http status code returned and json returned error, look for it if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') { - module.error(error.statusMessage + httpMessage); + module.error(error.statusMessage + httpMessage, ajaxSettings.url); } else { if(status == 'error' && settings.dataType == 'json') { @@ -767,7 +769,7 @@ $.api.settings = { namespace : 'api', debug : true, - verbose : true, + verbose : false, performance : true, // event binding diff --git a/src/definitions/modules/tab.js b/src/definitions/modules/tab.js index 9af6746ef..56ad47b77 100644 --- a/src/definitions/modules/tab.js +++ b/src/definitions/modules/tab.js @@ -75,10 +75,7 @@ $.fn.tab = function(parameters) { // set up automatic routing if(settings.auto) { - module.verbose('Setting up automatic tab retrieval from server'); - settings.apiSettings = { - url: (settings.path || '') + '/{$tab}' - }; + module.set.auto(); } // attach events if navigation wasn't set to window @@ -238,6 +235,22 @@ $.fn.tab = function(parameters) { }, set: { + auto: function() { + var + url = (typeof settings.path == 'string') + ? settings.path.replace(/\/$/, '') + '/{$tab}' + : '/{$tab}' + ; + module.verbose('Setting up automatic tab retrieval from server', url); + if($.isPlainObject(settings.apiSettings)) { + settings.apiSettings.url = url; + } + else { + settings.apiSettings = { + url: url + }; + } + }, state: function(state) { $.address.value(state); } @@ -370,22 +383,22 @@ $.fn.tab = function(parameters) { cachedContent = module.cache.read(fullTabPath); + module.activate.tab(tabPath); + if(settings.cache && cachedContent) { module.debug('Showing existing content', fullTabPath); module.content.update(tabPath, cachedContent); - module.activate.tab(tabPath); settings.onTabLoad.call($tab, tabPath, parameterArray, historyEvent); } else if(existingRequest) { module.debug('Content is already loading', fullTabPath); - $tab - .addClass(className.loading) - ; + $tab.addClass(className.loading); } else if($.api !== undefined) { - requestSettings = $.extend(true, { headers: { 'X-Remote': true } }, settings.apiSettings, apiSettings); + requestSettings = $.extend(true, { + headers: { 'X-Remote': true } + }, settings.apiSettings, apiSettings); module.debug('Retrieving remote content', fullTabPath, requestSettings); - console.log(existingRequest, requestSettings, cachedContent); $tab.api( requestSettings ); } else { diff --git a/tasks/admin/components/create.js b/tasks/admin/components/create.js index cc79be40b..4a2e15c7f 100644 --- a/tasks/admin/components/create.js +++ b/tasks/admin/components/create.js @@ -34,6 +34,7 @@ var rename = require('gulp-rename'), replace = require('gulp-replace'), tap = require('gulp-tap'), + util = require('gulp-util'), // config config = require('../../config/user'), @@ -72,6 +73,12 @@ module.exports = function(callback) { repoName = release.componentRepoRoot + capitalizedComponent, gitURL = 'https://github.com/' + release.org + '/' + repoName + '.git', repoURL = 'https://github.com/' + release.org + '/' + repoName + '/', + concatSettings = { + newline : '', + root : outputDirectory, + prepend : " '", + append : "'," + }, regExp = { match : { // templated values @@ -90,6 +97,7 @@ module.exports = function(callback) { formExport : /\$\.fn\.\w+\s*=\s*function\(fields, parameters\)\s*{/g, settingsExport : /\$\.fn\.\w+\.settings\s*=/g, settingsReference : /\$\.fn\.\w+\.settings/g, + trailingComma : /,(?=[^,]*$)/, jQuery : /jQuery/g, }, replace : { @@ -119,10 +127,13 @@ module.exports = function(callback) { notes : component + ' create release notes', composer : component + ' create composer.json', package : component + ' create package.json', - meteor : component + ' create package.js', + meteor : component + ' create meteor package.js', }, // paths to includable assets - assetPath = '/assets/**/' + component + '?(s).*' + manifest = { + assets : outputDirectory + '/assets/**/' + component + '?(s).*', + component : outputDirectory + '/' + component + '+(.js|.css)' + } ; // copy dist files into output folder adjusting asset paths @@ -265,32 +276,33 @@ module.exports = function(callback) { // Creates meteor package.js gulp.task(task.meteor, function() { var - fileNames = '' + filenames = '' ; - if(isJavascript) { - fileNames += ' \'' + component + '.js\',\n'; - } - if(isCSS) { - fileNames += ' \'' + component + '.css\',\n'; - } - return gulp.src(outputDirectory + assetPath, { base: outputDirectory}) - .pipe(concatFileNames('/dev/null', { - newline : '', - root : outputDirectory, - prepend : ' \'', - append : '\',' + return gulp.src(manifest.component) + .pipe(concatFileNames('empty.txt', concatSettings)) + .pipe(tap(function(file) { + filenames += file.contents; })) - .pipe(tap(function(file) { fileNames += file.contents; })) - .on('end', function(){ - gulp.src(release.templates.meteor.component) - .pipe(plumber()) - .pipe(flatten()) - .pipe(replace(regExp.match.name, regExp.replace.name)) - .pipe(replace(regExp.match.titleName, regExp.replace.titleName)) - .pipe(replace(regExp.match.version, version)) - .pipe(replace(regExp.match.files, fileNames)) - .pipe(rename(release.files.meteor)) - .pipe(gulp.dest(outputDirectory)) + .on('end', function() { + gulp.src(manifest.assets) + .pipe(concatFileNames('empty.txt', concatSettings)) + .pipe(tap(function(file) { + filenames += file.contents; + })) + .on('end', function() { + // remove trailing slash + filenames = filenames.replace(regExp.match.trailingComma, '').trim(); + gulp.src(release.templates.meteor.component) + .pipe(plumber()) + .pipe(flatten()) + .pipe(replace(regExp.match.name, regExp.replace.name)) + .pipe(replace(regExp.match.titleName, regExp.replace.titleName)) + .pipe(replace(regExp.match.version, version)) + .pipe(replace(regExp.match.files, filenames)) + .pipe(rename(release.files.meteor)) + .pipe(gulp.dest(outputDirectory)) + ; + }) ; }) ; diff --git a/tasks/admin/distributions/create.js b/tasks/admin/distributions/create.js index 82e2e2db9..bdcc76f99 100644 --- a/tasks/admin/distributions/create.js +++ b/tasks/admin/distributions/create.js @@ -65,6 +65,7 @@ module.exports = function(callback) { repoName = release.distRepoRoot + distribution, regExp = { match : { + files : '{files}', version : '{version}' } }, @@ -73,16 +74,69 @@ module.exports = function(callback) { repo : distribution + ' create repo', meteor : distribution + ' create meteor package.js', package : distribution + ' create package.json' - } + }, + gatherFiles, + createList ; + // get files for meteor + gatherFiles = function(dir) { + var + dir = dir || path.resolve('.'), + list = fs.readdirSync(dir), + omitted = [ + '.git', + 'node_modules', + 'package.js', + 'package.json', + 'bower.json', + '.gitignore' + ] + files = [] + ; + list.forEach(function(file) { + var + isOmitted = (omitted.indexOf(file) > -1), + filePath = path.join(dir, file), + stat = fs.statSync(filePath) + ; + if(!isOmitted) { + if(stat && stat.isDirectory()) { + files = files.concat(gatherFiles(filePath)); + } + else { + files.push(filePath.replace(outputDirectory + path.sep, '')); + } + } + }) + return files + }; + + // spaces out list correctly + createList = function(files) { + var filenames = ''; + for(file in files) { + if(file == (files.length - 1) ) { + filenames += "'" + files[file] + "'"; + } + else { + filenames += "'" + files[file] + "',\n "; + } + } + return filenames; + }; + gulp.task(task.meteor, function() { + var + files = gatherFiles(outputDirectory) + filenames = createList(files) + ; gulp.src(release.templates.meteor[distLowerCase]) .pipe(plumber()) - .pipe(debug()) .pipe(flatten()) .pipe(replace(regExp.match.version, version)) + .pipe(replace(regExp.match.files, filenames)) .pipe(rename(release.files.meteor)) .pipe(gulp.dest(outputDirectory)) ; @@ -101,6 +155,7 @@ module.exports = function(callback) { else if(distribution == 'LESS') { gulp.task(task.repo, function() { return gulp.src('./src/theme.config.example', { base: './src/' }) + .pipe(gulp.src('./src/theme.less', { base: './src/' })) .pipe(gulp.src('./src/definitions/**/*', { base: './src/' })) .pipe(gulp.src('./src/_site/**/*', { base: './src/' })) .pipe(gulp.src('./src/themes/**/*', { base: './src/' })) diff --git a/tasks/admin/publish.js b/tasks/admin/publish.js new file mode 100644 index 000000000..2e196f9a0 --- /dev/null +++ b/tasks/admin/publish.js @@ -0,0 +1,24 @@ +/******************************* + Release All +*******************************/ + +/* + This task update all SUI individual component repos with new versions of components + + * Commits changes from create components to GitHub and Tags + +*/ + +var + runSequence = require('run-sequence') +; + +/* Release All */ +module.exports = function() { + + runSequence( + 'update distributions', // commit less/css versions to github + 'update components' // commit components to github + ); + +}; \ No newline at end of file diff --git a/tasks/admin/register-repos.js b/tasks/admin/register.js similarity index 100% rename from tasks/admin/register-repos.js rename to tasks/admin/register.js diff --git a/tasks/admin/release-all.js b/tasks/admin/release-all.js deleted file mode 100644 index 20df1f9dd..000000000 --- a/tasks/admin/release-all.js +++ /dev/null @@ -1,29 +0,0 @@ -/******************************* - Release All -*******************************/ - -/* - This task update all SUI individual component repos with new versions of components - - * Initializes repositories with current versions - * Creates local files at ../components/ with each repo for release - * Commits changes from create components - * Registers new versions with NPM Publish - -*/ - -var - runSequence = require('run-sequence') -; - -/* Release All */ -module.exports = function() { - - runSequence( - 'build', // build Semantic - 'init components', // sync with current github version - 'create components', // update each repo - 'update components' // commit changes to github - ); - -}; \ No newline at end of file diff --git a/tasks/admin/release.js b/tasks/admin/release.js index f37992879..e25afdbfb 100644 --- a/tasks/admin/release.js +++ b/tasks/admin/release.js @@ -7,8 +7,6 @@ * Initializes repositories with current versions * Creates local files at ../distributions/ with each repo for release - * Commits changes from create components - * Registers new versions with NPM Publish */ @@ -23,7 +21,8 @@ module.exports = function() { 'build', // build Semantic 'init distributions', // sync with current github version 'create distributions', // update each repo with changes from master repo - 'update distributions' // commit changes to github + 'init components', // sync with current github version + 'create components' // update each repo ); }; \ No newline at end of file diff --git a/tasks/build.js b/tasks/build.js index 2f4e8342c..6dfd36a90 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -61,7 +61,7 @@ module.exports = function(callback) { // check for right-to-left language if(config.rtl === true || config.rtl === 'Yes') { - gulp.start('build rtl'); + gulp.start('build-rtl'); return; } diff --git a/tasks/collections/admin.js b/tasks/collections/admin.js index 21fe420f1..a384d1fab 100644 --- a/tasks/collections/admin.js +++ b/tasks/collections/admin.js @@ -26,25 +26,24 @@ module.exports = function(gulp) { createDistributions = require('../admin/distributions/create'), updateDistributions = require('../admin/distributions/update'), - // one time register with PM - registerRepos = require('../admin/register-repos'), - - // meta tasks - releaseAll = require('../admin/release-all'), - release = require('../admin/release') + release = require('../admin/release'), + publish = require('../admin/publish'), + register = require('../admin/register') ; - gulp.task('release', 'Publishes only packaged releases', release); - gulp.task('release all', 'Publishes all releases (components, package)', releaseAll); - + /* Release */ gulp.task('init distributions', 'Grabs each component from GitHub', initDistributions); gulp.task('create distributions', 'Updates files in each repo', createDistributions); - gulp.task('update distributions', 'Commits component updates from create to GitHub', updateDistributions); - gulp.task('init components', 'Grabs each component from GitHub', initComponents); gulp.task('create components', 'Updates files in each repo', createComponents); + + /* Publish */ + gulp.task('update distributions', 'Commits component updates from create to GitHub', updateDistributions); gulp.task('update components', 'Commits component updates from create to GitHub', updateComponents); - gulp.task('register repos', 'Registers all packages with NPM', registerRepos); + /* Tasks */ + gulp.task('release', 'Stages changes in GitHub repos for all distributions', release); + gulp.task('publish', 'Publishes all releases (components, package)', publish); + gulp.task('register', 'Registers all packages with NPM', register); }; \ No newline at end of file diff --git a/tasks/config/admin/release.js b/tasks/config/admin/release.js index 5694a30b6..7b8cb18b4 100644 --- a/tasks/config/admin/release.js +++ b/tasks/config/admin/release.js @@ -61,6 +61,7 @@ module.exports = { // components that get separate repositories for bower/npm components : [ 'accordion', + 'ad', 'api', 'breadcrumb', 'button', diff --git a/tasks/config/admin/templates/component-package.js b/tasks/config/admin/templates/component-package.js index 0f4c199ab..74cd51b9d 100644 --- a/tasks/config/admin/templates/component-package.js +++ b/tasks/config/admin/templates/component-package.js @@ -1,10 +1,7 @@ -var - where = 'client' // Adds files only to the client -; Package.describe({ name : 'semantic:ui-{component}', - summary : 'Semantic UI - {Component} (official): Single component release of {component}', + summary : 'Semantic UI - {Component}: Single component release', version : '{version}', git : 'git://github.com/Semantic-Org/UI-{Component}.git', }); @@ -13,5 +10,5 @@ Package.onUse(function(api) { api.versionsFrom('1.0'); api.addFiles([ {files} - ], where); + ], 'client'); }); diff --git a/tasks/config/admin/templates/css-package.js b/tasks/config/admin/templates/css-package.js index 3d5b64983..ad17ade93 100644 --- a/tasks/config/admin/templates/css-package.js +++ b/tasks/config/admin/templates/css-package.js @@ -11,37 +11,10 @@ Package.describe({ Package.onUse(function(api) { - var - fs = require('fs'), - path = require('path'), - files, - walk - ; - - // recursive sync walk - walk = function(dir) { - var - dir = dir || __dirname, - list = fs.readdirSync(dir), - files = [] - ; - list.forEach(function(file) { - var - filePath = path.join(dir, file), - stat = fs.statSync(filePath) - ; - if(stat && stat.isDirectory() && file !== 'node_modules') { - files = files.concat(walk(filePath)); - } - else { - files.push(filePath); - } - }) - return files - } - files = walk(); - api.versionsFrom('1.0'); - api.addFiles(files, 'clent'); + + api.addFiles([ + {files} + ], 'client'); }); diff --git a/tasks/config/admin/templates/less-package.js b/tasks/config/admin/templates/less-package.js index 197da5714..e2f8a253d 100644 --- a/tasks/config/admin/templates/less-package.js +++ b/tasks/config/admin/templates/less-package.js @@ -11,37 +11,11 @@ Package.describe({ Package.onUse(function(api) { - var - fs = require('fs'), - path = require('path'), - files, - walk - ; - - // recursive sync walk - walk = function(dir) { - var - dir = dir || __dirname, - list = fs.readdirSync(dir), - files = [] - ; - list.forEach(function(file) { - var - filePath = path.join(dir, file), - stat = fs.statSync(filePath) - ; - if(stat && stat.isDirectory() && file !== 'node_modules') { - files = files.concat(walk(filePath)); - } - else { - files.push(filePath); - } - }) - return files - } - files = walk(); - api.versionsFrom('1.0'); - api.addFiles(files, 'clent'); + api.use('less', 'client'); + + api.addFiles([ + {files} + ], 'client'); }); diff --git a/tasks/watch.js b/tasks/watch.js index c5c34f89d..619792c2f 100644 --- a/tasks/watch.js +++ b/tasks/watch.js @@ -59,7 +59,7 @@ module.exports = function(callback) { // check for right-to-left language if(config.rtl === true || config.rtl === 'Yes') { - gulp.start('watch rtl'); + gulp.start('watch-rtl'); return; }