diff --git a/.gitignore b/.gitignore index 53d15cd..cfe12ae 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ node_modules bower_components .tmp/ **.mo +.idea/** diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index d0a5dc3..aed1947 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,17 @@ sudo: false language: python python: -- 2.7 + - 2.7 +node_js: + - "6.2" cache: pip +before_install: + - nvm install 6.2 install: -- npm install -g gulp -- npm install -g bower -- pip install grow + - nvm use 6.2 + - npm install -g gulp + - npm install -g bower + - pip install grow script: -- grow install -- grow build + - grow install + - grow build \ No newline at end of file diff --git a/bower.json b/bower.json index 84a55b1..d2afb5d 100644 --- a/bower.json +++ b/bower.json @@ -1,12 +1,9 @@ { "name": "scaffold", "private": true, - "dependencies": { - "angular": "1.5.7" - }, "devDependencies": { - "closure-compiler": "http://dl.google.com/closure-compiler/compiler-latest.zip", - "closure-library": "git://github.com/google/closure-library.git", - "closure-compiler-src": "git://github.com/google/closure-compiler.git" + "closure-compiler": "http://dl.google.com/closure-compiler/compiler-20170124.zip", + "closure-library": "git://github.com/google/closure-library.git#68284ff", + "closure-compiler-src": "git://github.com/google/closure-compiler.git#7eb7513" } } diff --git a/content/pages/_blueprint.yaml b/content/pages/_blueprint.yaml index 084d177..5bc896d 100644 --- a/content/pages/_blueprint.yaml +++ b/content/pages/_blueprint.yaml @@ -3,3 +3,6 @@ view: /views/base.html localization: path: /intl/{locale}/{base}/ + +title@: Grow Scaffold +description@: Grow Scaffold theme with Google modules diff --git a/content/pages/another.md b/content/pages/another.md index e4f0734..88d2e22 100644 --- a/content/pages/another.md +++ b/content/pages/another.md @@ -1,10 +1,32 @@ ---- -$title@: Another Page ---- -# {{_('Another page.')}} +---- +$title@: Home +path: /another/ -Unlike the first page, this page is Markdown-formatted. +$localization: + path: /intl/{locale}/{base} +hero: + title@: Hello World! + subtitle@: Lorem ipsum dolor sit amet. +ctas: + - title@: Callout 1 + subtitle@: Description 1. + - title@: Callout 2 + subtitle@: Description 2. + - title@: Callout 3 + subtitle@: Description 3. +---- +

{{_(doc.hero.title)}}

+

{{_(doc.hero.subtitle)}}

-1. Which means -1. you can -1. use Markdown-formatted lists. +
+
+ + +
+
+ + \ No newline at end of file diff --git a/content/pages/home.html b/content/pages/home.html deleted file mode 100644 index 24ee657..0000000 --- a/content/pages/home.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -$title@: Home -$path: / - -$localization: - path: /intl/{locale}/ - -hero: - title@: Hello World! - subtitle@: Lorem ipsum dolor sit amet. -ctas: -- title@: Callout 1 - subtitle@: Description 1. -- title@: Callout 2 - subtitle@: Description 2. -- title@: Callout 3 - subtitle@: Description 3. ---- -

{{_(doc.hero.title)}}

-

{{_(doc.hero.subtitle)}}

- -
-
- - -
-
- - diff --git a/content/pages/home.yaml b/content/pages/home.yaml new file mode 100644 index 0000000..481da0f --- /dev/null +++ b/content/pages/home.yaml @@ -0,0 +1,6 @@ +$title@: Home +$path: / +$view: /views/pages/home.html + +$localization: + path: /intl/{locale}/ \ No newline at end of file diff --git a/gulp/config.js b/gulp/config.js index c1f4084..c638267 100644 --- a/gulp/config.js +++ b/gulp/config.js @@ -9,8 +9,5 @@ module.exports = { JS_TEMP_DIR: './.tmp/', JS_SOURCES: './source/js/**/*.js', BOWER_FOLDER: './bower_components/', - CLOSURE_EXTERNS: [ - './bower_components/closure-compiler-src/externs/browser/**/*.js' - ] } } diff --git a/gulp/tasks/scripts.js b/gulp/tasks/scripts.js index 99f304c..3a90ce4 100644 --- a/gulp/tasks/scripts.js +++ b/gulp/tasks/scripts.js @@ -1,61 +1,53 @@ -'use strict' -var gulp = require('gulp'); -var runSequence = require('run-sequence'); -var filenames = require('gulp-filenames'); -var concat = require('gulp-concat'); -var closureCompiler = require('gulp-closure-compiler'); -var uglify = require('gulp-uglify'); -var config = require('../config'); +'use strict'; + +const gulp = require('gulp'); +const runSequence = require('run-sequence'); +const concat = require('gulp-concat'); +const closureCompiler = require('gulp-closure-compiler'); +const argv = require('yargs').argv; +const rimraf = require('rimraf'); +const uglify = require('gulp-uglify'); +const config = require('../config'); + +const ENV_PRODUCTION = argv.env == 'PROD'; gulp.task('compile_js', function() { - var closureOpts = { - compilerPath: './bower_components/closure-compiler/compiler.jar', + + const OPT_LEVEL = ENV_PRODUCTION ? + 'ADVANCED_OPTIMIZATIONS' : + 'SIMPLE_OPTIMIZATIONS'; + + const closureOpts = { + compilerPath: './bower_components/closure-compiler/closure-compiler-v20170124.jar', compilerFlags: { - angular_pass: true, - closure_entry_point: 'scaffold', - compilation_level: 'SIMPLE_OPTIMIZATIONS', - generate_exports: true, - manage_closure_dependencies: true, - only_closure_dependencies: true, - output_wrapper: '(function(){%output%})();', - js: [ - './bower_components/closure-library/closure/**.js', - './bower_components/closure-library/third_party/**.js', - '!**_test.js' - ] + angular_pass: true, + closure_entry_point: 'goog:app.bootstrap', + compilation_level: OPT_LEVEL, + output_wrapper: '(function(){%output%})();', + generate_exports: true, + export_local_property_definitions: true, + js: [ + './bower_components/closure-library/closure/goog/base.js', + '!**_test.js', + '!**_spec.js' + ], + externs: [ + './bower_components/closure-compiler-src/contrib/externs/angular-1.6*.js' + ] }, - maxBuffer: 800000, // Set maxBuffer to .8GB - fileName: 'build.min.js' + maxBuffer: 800000, // .8GB + fileName: 'main.min.js' }; - var externs = []; - externs.concat(filenames.get('closure_externs')); - - closureOpts.compilerFlags.externs = externs - - return gulp.src(config.Path.JS_SOURCES) + return gulp + .src(config.Path.JS_SOURCES) .pipe(closureCompiler(closureOpts)) - .pipe(gulp.dest(config.Path.JS_TEMP_DIR)) -}); - -gulp.task('minify_js', function() { - return gulp.src([ - config.Path.JS_TEMP_DIR + 'build.min.js' - ]) - .pipe(concat('main.min.js')) .pipe(uglify()) .pipe(gulp.dest(config.Path.JS_OUT_DIR)); }); -gulp.task('build_js', function(callback) { - return runSequence( - 'get_closure_externs_paths', - 'compile_js', - 'minify_js', - callback); -}); - -gulp.task('get_closure_externs_paths', function() { - return gulp.src(config.Path.CLOSURE_EXTERNS) - .pipe(filenames('closure_externs')) +gulp.task('clean', function(callback) { + rimraf('./build', callback); }) + +gulp.task('build_js', ['compile_js']); \ No newline at end of file diff --git a/gulp/tasks/styles.js b/gulp/tasks/styles.js index 5ab23b8..8b43e7a 100644 --- a/gulp/tasks/styles.js +++ b/gulp/tasks/styles.js @@ -1,16 +1,17 @@ -'use strict' -var gulp = require('gulp'); -var autoprefixer = require('gulp-autoprefixer'); -var plumber = require('gulp-plumber'); -var sass = require('gulp-sass'); -var config = require('../config'); +'use strict'; + +const gulp = require('gulp'); +const autoprefixer = require('gulp-autoprefixer'); +const plumber = require('gulp-plumber'); +const sass = require('gulp-sass'); +const csso = require('gulp-csso'); +const config = require('../config'); gulp.task('sass', function() { return gulp.src(config.Path.CSS_SOURCES) .pipe(plumber()) - .pipe(sass({ - outputStyle: 'compressed' - })) + .pipe(sass()) .pipe(autoprefixer()) + .pipe(csso()) .pipe(gulp.dest(config.Path.CSS_OUT_DIR)); }); diff --git a/gulp/tasks/watch.js b/gulp/tasks/watch.js index 9865992..0c3dac6 100644 --- a/gulp/tasks/watch.js +++ b/gulp/tasks/watch.js @@ -1,6 +1,7 @@ 'use strict'; -var gulp = require('gulp'); -var config = require('../config'); + +const gulp = require('gulp'); +const config = require('../config'); gulp.task('watch', function() { gulp.watch([config.Path.CSS_SOURCES], ['sass']); diff --git a/gulpfile.js b/gulpfile.js index 6cb860a..f6ec0ec 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,15 +1,20 @@ -var fs = require('fs'); -var gulp = require('gulp'); +const fs = require('fs'); +const gulp = require('gulp'); +const runSequence = require('run-sequence'); +const argv = require('yargs').argv; + /** - * This will load all js or coffee files in the gulp directory + * This will load all js files in the gulp directory * in order to load all gulp tasks */ fs.readdirSync('./gulp/tasks').filter(function(file) { - return (/\.(js|coffee)$/i).test(file); + return (/\.js$/i).test(file); }).map(function(file) { require('./gulp/tasks/' + file); }); -gulp.task('build', ['build_js', 'sass']); +gulp.task('build', function(callback){ + runSequence('clean', ['build_js', 'sass'], callback) +}); gulp.task('default', ['build', 'watch']); diff --git a/package.json b/package.json index 926768a..f7d3aec 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,21 @@ { "name": "scaffold", "private": true, + "engines": { + "node": "^6.2.0" + }, "devDependencies": { "bower": "^1.3.12", "gulp": "^3.8.11", "gulp-autoprefixer": "^2.1.0", "gulp-closure-compiler": "^0.2.17", "gulp-concat": "^2.5.2", - "gulp-filenames": "^2.0.0", + "gulp-csso": "^2.0.0", "gulp-plumber": "^1.0.0", "gulp-sass": "^2.1.1", - "gulp-uglify": "^1.2.0", - "run-sequence": "^1.0.2" + "gulp-uglify": "^2.0.1", + "rimraf": "^2.6.0", + "run-sequence": "^1.0.2", + "yargs": "^6.6.0" } } diff --git a/podspec.yaml b/podspec.yaml index 6879f5f..aa3ebad 100644 --- a/podspec.yaml +++ b/podspec.yaml @@ -1,11 +1,10 @@ -grow_version: ">=0.0.60" +grow_version: ">=0.0.67" localization: default_locale: en_US locales: - - de_DE - - en_US - - ja_JP + - en_US + - ja_JP static_dirs: - static_dir: /source/images/ @@ -15,3 +14,5 @@ static_dirs: preprocessors: - kind: gulp + build_task: "build --env=PROD" + run_task: "default --env=DEV" diff --git a/source/js/demo_controller.js b/source/js/demo_controller.js deleted file mode 100644 index 1059059..0000000 --- a/source/js/demo_controller.js +++ /dev/null @@ -1,18 +0,0 @@ -goog.provide('scaffold.controllers.DemoController'); - - -/** @constructor @ngInject */ -scaffold.controllers.DemoController = function($element, $scope, $http) { - this.$element = $element; - this.$http = $http; - this.$scope = $scope; - this.text = null; -}; - - -/** @export */ -scaffold.controllers.DemoController.prototype.sayHello = function(value) { - var el = this.$element[0]; - var buttonEl = el.querySelector('button'); - buttonEl.textContent = value; -}; diff --git a/source/js/main.js b/source/js/main.js deleted file mode 100644 index 5638e92..0000000 --- a/source/js/main.js +++ /dev/null @@ -1,11 +0,0 @@ -goog.provide('scaffold'); - -goog.require('scaffold.controllers.DemoController'); - - -/** @export */ -scaffold.main = function() { - angular.module('scaffold', []) - .controller('DemoController', scaffold.controllers.DemoController) - angular.bootstrap(document, ['scaffold']); -}; diff --git a/source/js/sample/app.component.js b/source/js/sample/app.component.js new file mode 100644 index 0000000..6126131 --- /dev/null +++ b/source/js/sample/app.component.js @@ -0,0 +1,91 @@ +goog.module('app.MainComponent'); + +/** + * @type {!angular.ComponentController} + */ +const controller = goog.defineClass(null, { + + /** @ngInject */ + constructor: function(PeopleService) { + + /** @private */ + this.peopleService_ = PeopleService; + + /** @export {boolean} */ + this.loading = false; + + /** @export {string} */ + this.title = 'Main'; + + /** @export {Date} */ + this.date = new Date(); + + /** @export {string} */ + this.dateString = ''; + + /** @export {Array} */ + this.list = []; + + /** + * Normalized locale code for Date#toLocaleString() + * @private {string} + */ + this.lang_ = document + .querySelector('html') + .getAttribute('lang') + .replace('_', '-') + .toLowerCase(); + }, + + /** + * Sets the formatted string of the chosen date. + * @export + */ + pickTime() { + if (!this.date) { + return; + } + + this.dateString = this.date.toLocaleString(this.lang_); + }, + + /** + * Simulates an async call with fat arrow assignment. + * @export + */ + showPeople() { + this.loading = true; + + this.peopleService_.getList() + .then(results => { + this.list = results; + }) + .finally(() => { + this.loading = false; + }) + } +}); + +/** + * @type {!angular.Component} + */ +const componentDef = { + controller: controller, + template: ` + Sample Component: +

{[ $ctrl.title ]}

+ +

{[ $ctrl.dateString ]}

+
+ + Loading... +
+{[ $ctrl.list | json ]}
+  
+ ` +}; + +exports = { + selector: 'appMain', + definition: componentDef +} diff --git a/source/js/sample/app.service.js b/source/js/sample/app.service.js new file mode 100644 index 0000000..468a363 --- /dev/null +++ b/source/js/sample/app.service.js @@ -0,0 +1,44 @@ +goog.module('app.PeopleService'); + +/** + * @typedef {{firstName: string, age: number}} + */ +app.Person; + +const PeopleService = goog.defineClass(null, { + /** + * @ngInject + * @param {!angular.$q} $q Promise service + * @param {!angular.$timeout} $timeout Timeout service + */ + constructor($q, $timeout) { + this.q_ = $q; + this.timeout_ = $timeout; + + /** + * Sample results list of people. + * @type {Array} + * @private + */ + this.result_ = [ + { 'firstName': 'John', 'age': 25 }, + { 'firstName': 'Sandra', 'age': 31 }, + ]; + }, + + /** + * @return {angular.$q.Promise>} + */ + getList() { + const defer = this.q_.defer(); + this.timeout_(() => { + defer.resolve(this.result_); + }, 1000); + return defer.promise; + } +}); + +exports = { + name: 'PeopleService', + definition: PeopleService +} \ No newline at end of file diff --git a/source/js/sample/main.controller.js b/source/js/sample/main.controller.js new file mode 100644 index 0000000..f1fd65d --- /dev/null +++ b/source/js/sample/main.controller.js @@ -0,0 +1,24 @@ +goog.module('app.MainController'); + +/** + * @type {!angular.$controller} + */ +const controller = goog.defineClass(null, { + constructor() { + /** @export {string} */ + this.text = ''; + }, + + /** + * @export + * @param {string} value + */ + sayHello(value) { + alert(`Hello there, ${value}!`); + } +}); + +exports = { + name: 'MainController', + definition: controller +} diff --git a/source/js/sample/main.js b/source/js/sample/main.js new file mode 100644 index 0000000..1cc0a54 --- /dev/null +++ b/source/js/sample/main.js @@ -0,0 +1,27 @@ +goog.module('bootstrap'); + +const mainComponent = goog.require('app.MainComponent'); +const mainController = goog.require('app.MainController'); +const peopleService = goog.require('app.PeopleService'); + +function bootstrap() { + angular.module('app', []) + .component(mainComponent.selector, mainComponent.definition) + .controller(mainController.name, mainController.definition) + .service(peopleService.name, peopleService.definition) + .config(['$compileProvider', '$interpolateProvider', + function($compileProvider, $interpolateProvider) { + + // Disable debug info in production + if (/localhost/.test(window.location.host) === false) { + $compileProvider.debugInfoEnabled(false); + } + + $interpolateProvider.startSymbol('{['); + $interpolateProvider.endSymbol(']}'); + }]) + + angular.bootstrap(document, ['app']); +}; + +goog.exportSymbol('app.bootstrap', bootstrap); diff --git a/source/sass/_config.scss b/source/sass/_config.scss deleted file mode 100644 index f857e18..0000000 --- a/source/sass/_config.scss +++ /dev/null @@ -1,3 +0,0 @@ -$color-fg: #333; -$color-bg: #efefef; -$font-family: 'RobotoDraft', 'Helvetica', arial, sans-serif; diff --git a/source/sass/main.min.scss b/source/sass/main.min.scss deleted file mode 100644 index 64c7bdf..0000000 --- a/source/sass/main.min.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import '_config.scss'; -@import '_global.scss'; diff --git a/source/sass/main.scss b/source/sass/main.scss new file mode 100644 index 0000000..fae7a81 --- /dev/null +++ b/source/sass/main.scss @@ -0,0 +1 @@ +@import 'sample/main' \ No newline at end of file diff --git a/source/sass/sample/_config.scss b/source/sass/sample/_config.scss new file mode 100644 index 0000000..331d65e --- /dev/null +++ b/source/sass/sample/_config.scss @@ -0,0 +1,3 @@ +$color-fg: #333; +$color-bg: #efefef; +$font-family: 'RobotoDraft', 'Helvetica', arial, sans-serif; \ No newline at end of file diff --git a/source/sass/_global.scss b/source/sass/sample/_global.scss similarity index 100% rename from source/sass/_global.scss rename to source/sass/sample/_global.scss diff --git a/source/sass/sample/_layout.scss b/source/sass/sample/_layout.scss new file mode 100644 index 0000000..0cb6221 --- /dev/null +++ b/source/sass/sample/_layout.scss @@ -0,0 +1,10 @@ +app-main { + display: inline-block; + border: 5px dotted #AAA; + padding: 10px; + margin: 20px; + + p { + font-size: 11px; + } +} \ No newline at end of file diff --git a/source/sass/sample/main.scss b/source/sass/sample/main.scss new file mode 100644 index 0000000..d3e2054 --- /dev/null +++ b/source/sass/sample/main.scss @@ -0,0 +1,3 @@ +@import 'config'; +@import 'global'; +@import 'layout'; \ No newline at end of file diff --git a/views/base.html b/views/base.html index f293c52..78216fd 100644 --- a/views/base.html +++ b/views/base.html @@ -1,21 +1,31 @@ + - {{_(doc.title)}} - - - + + + {{ _(doc.title) }} + + + - + +
+
- {% block main %} - {{doc.html|render|safe}} - {% endblock %} + {% block main %} {{doc.html|render|safe}} {% endblock %}
- - + + - + + \ No newline at end of file diff --git a/views/pages/home.html b/views/pages/home.html new file mode 100644 index 0000000..f805805 --- /dev/null +++ b/views/pages/home.html @@ -0,0 +1,5 @@ +{% extends "/views/base.html" %} + +{% block main %} + +{% endblock %} \ No newline at end of file