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.
+
+
+
+
+
+{% for cta in doc.ctas %}
+- {{_(cta.title)}}: {{_(cta.subtitle)}}
+{% endfor %}
+
\ 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)}}
-
-
-
-
-
-
- {% for cta in doc.ctas %}
- - {{_(cta.title)}}: {{_(cta.subtitle)}}
- {% endfor %}
-
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