Skip to content

Commit

Permalink
Update master from talk-template and browser-template
Browse files Browse the repository at this point in the history
Refresh for cohort 016
  • Loading branch information
MicFin committed Jan 18, 2017
1 parent 818e97d commit 7d3a6c0
Show file tree
Hide file tree
Showing 20 changed files with 594 additions and 322 deletions.
568 changes: 284 additions & 284 deletions .gitignore

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .scss-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exclude: 'node_modules/*'
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![General Assembly Logo](http://i.imgur.com/ke8USTq.png)
[![General Assembly Logo](https://camo.githubusercontent.com/1a91b05b8f4d44b5bbfb83abac2b0996d8e26c92/687474703a2f2f692e696d6775722e636f6d2f6b6538555354712e706e67)](https://generalassemb.ly/education/web-development-immersive)

# HTML & CSS Layout

Expand Down Expand Up @@ -209,4 +209,5 @@ understanding is [this CSS-tricks blog post](https://css-tricks.com/absolute-pos
## [License](LICENSE)

1. All content is licensed under a CC­BY­NC­SA 4.0 license.
1. All software code is licensed under GNU GPLv3. For commercial use or alternative licensing, please contact [email protected].
1. All software code is licensed under GNU GPLv3. For commercial use or
alternative licensing, please contact [email protected].
9 changes: 9 additions & 0 deletions assets/scripts/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';

const config = {
apiOrigins: {
production: 'https://ga-wdi-boston.herokuapp.com',
},
};

module.exports = config;
11 changes: 9 additions & 2 deletions assets/scripts/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
'use strict';

// user require with a reference to bundle the file and use it in this file
// var example = require('./example');
const setAPIOrigin = require('../../lib/set-api-origin');
const config = require('./config');

$(() => {
setAPIOrigin(location, config);
});

// use require with a reference to bundle the file and use it in this file
// const example = require('./example');

// use require without a reference to ensure a file is bundled
require('./example');
6 changes: 6 additions & 0 deletions assets/scripts/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

const store = {
};

module.exports = store;
Empty file.
65 changes: 65 additions & 0 deletions forms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Forms

Developers should use `getFormFields` to retrieve data from html forms for API
requests.

`getFormFields` only retrieves data from form elements with a name attribute.

The object returned can be used to validate the form data.

**in `api.js`**

```js
'use strict';

const ajaxDefaults = {
url: 'http://localhost:3000',
};

const myRequest = (data, success, fail) => {
$.ajax(Object.assign({ method: 'POST', data }, ajaxDefaults))
.done(success)
.fail(fail);
};

module.exports = {
myRequest,
};
```

**in `ui.js`**

```js
'use strict';

const success = (data) => {
// handle success
};

const failure = (err) => {
// handle failure
};

module.exports = {
success,
failure,
}
```

**in `index.js`**

```js
'use strict';

const getFormFields = require('../../lib/get-form-fields');
const api = require('./api');
const ui = require('./ui');

$(() => {
$('#my-form').on('submit', function (e) {
let data = getFormFields(this);
e.preventDefault();
api.myRequest(data, ui.success, ui.failure);
});
});
```
7 changes: 7 additions & 0 deletions grunt/aliases.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"default": ["nag"],
"deploy": [
"shell:git-is-clean",
"shell:git-push-master",
"shell:deploy-prepare",
"build",
"shell:deploy-publish"
],
"build": ["webpack:build"],
"server": ["webpack-dev-server:start"],
"serve": ["server"],
Expand Down
4 changes: 2 additions & 2 deletions grunt/jasmine.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"tests": {
"src": ["vendor.bundle.js", "bundle.js"],
"src": ["public/vendor.js", "public/application.js"],
"options": {
"specs": "specs.js"
"specs": "public/specs.js"
}
}
}
39 changes: 39 additions & 0 deletions grunt/shell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

const ghPagesList = [
'index.html',
'favicon.ico',
'public',
].join(' ');

module.exports = {
'git-is-clean': {
// `$(git status --porcelain)` will evaluate to the empty string if the
// working directory is clean.
// `test -z` will exit 0 (true) if its argument is an empty string.
// If it doesn't exit true, `(git status && false)` will show why the
// repository isn't clean and exit false causing the grunt tasks to end.
command: 'test -z "$(git status --porcelain)" || (git status && false)',
},
'git-push-master': {
command: 'git push origin master',
},
'deploy-prepare': {
command: [
'git checkout master',
'git branch -D gh-pages || echo "so not removed"',
'git checkout --orphan gh-pages',
'git rm --cached \'*\'',
].join(' && '),
},
'deploy-publish': {
command: [
'touch .nojekyll',
`git add --force .nojekyll ${ghPagesList}`,
'git commit -m "deploy task"',
'git push origin gh-pages --force',
'git clean -x -d --force --exclude=node_modules',
'git checkout master',
].join(' && '),
},
};
13 changes: 11 additions & 2 deletions grunt/webpack-dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@ let clone = require('clone');
// clone the webpack config to separate configuration of webpack and dev server
let webpackConfig = clone(require('./webpack').options);

// enable live reload without a script tag
webpackConfig.entry.vendor.unshift('webpack-dev-server/client?http://localhost:8080');
// port for development server
const port = +('GA'.split('').reduce((p, c)=> p + c.charCodeAt(), ''));

// make `jQuery` and `$` available in the development console
webpackConfig.module.loaders.push({
test: require.resolve('jquery'),
loader: 'expose?jQuery!expose?$',
});

module.exports = {
options: {
port,
inline: true, // reload on change
webpack: webpackConfig,
publicPath: '/public/',
},

start: {
Expand Down
24 changes: 17 additions & 7 deletions grunt/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ let path = require('path');
module.exports = {
options: {
entry: {
bundle: './index.js',
application: './index.js',
specs: './spec/_all.js',
vendor: ['jquery', 'bootstrap-sass'],
},

output: {
path: './',
filename: '[name].js',
path: __dirname + '/../public',
publicPath: 'public/',
},

plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Expand Down Expand Up @@ -56,14 +60,20 @@ module.exports = {
{
test: /\.(hbs|handlebars)$/,
loader: 'handlebars-loader',
},
{
test: /\.html\.(hbs|handlebars)$/,
loader: 'handlebars-loader!html',
query: {
helperDirs: [
__dirname + '/../assets/scripts/templates/helpers',
],
},
},
],
},

resolve: {
alias: {
handlebars: 'handlebars/dist/handlebars.js',
},
},
stats: {
colors: true,
modules: true,
Expand Down
5 changes: 0 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,3 @@ require('./assets/scripts/index.js');

// styles
require('./assets/styles/index.scss');
require('./assets/styles/style.css');

// attach jQuery globally
require('expose?$!jquery');
require('expose?jQuery!jquery');
25 changes: 25 additions & 0 deletions lib/add-nested-value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

const addNestedValue = function (pojo, name, value) {
const recurse = function recurse(pojo, keys, value) {
value = decodeURIComponent(value);
let key = decodeURIComponent(keys.shift());
let next = keys[0];
if (next === '') { // key is an array
pojo[key] = pojo[key] || [];
pojo[key].push(value);
} else if (next) { // key is a parent key
pojo[key] = pojo[key] || {};
recurse(pojo[key], keys, value);
} else { // key is the key for value
pojo[key] = value;
}

return pojo;
};

let keys = name.split('[').map((k) => k.replace(/]$/, ''));
return recurse(pojo, keys, value);
};

module.exports = addNestedValue;
41 changes: 41 additions & 0 deletions lib/get-form-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

const addNestedValue = require('./add-nested-value');

const getFormFields = (form) => {
let target = {};

let elements = form.elements || [];
for (let i = 0; i < elements.length; i++) {
let e = elements[i];
if (!e.hasAttribute('name')) {
continue;
}

let type = 'TEXT';
switch (e.nodeName.toUpperCase()) {
case 'SELECT':
type = e.hasAttribute('multiple') ? 'MULTIPLE' : type;
break;
case 'INPUT':
type = e.getAttribute('type').toUpperCase();
break;
}

let name = e.getAttribute('name');

if (type === 'MULTIPLE') {
for (let i = 0; i < e.length; i++) {
if (e[i].selected) {
addNestedValue(target, name, e[i].value);
}
}
} else if ((type !== 'RADIO' && type !== 'CHECKBOX') || e.checked) {
addNestedValue(target, name, e.value);
}
}

return target;
};

module.exports = getFormFields;
16 changes: 16 additions & 0 deletions lib/parse-nested-query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const addNestedValue = require('./add-nested-value');

const parseNestedQuery = queryString =>
queryString.split('&')
.reduce((memo, element) => {
if (element) {
let keyValuePair = element.split('=');
memo = addNestedValue(memo, keyValuePair[0], keyValuePair[1]);
}

return memo;
}, {});

module.exports = parseNestedQuery;
37 changes: 37 additions & 0 deletions lib/set-api-origin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

const parseNestedQuery = require('./parse-nested-query');

/*
possibilites to handle and example URLs:
client local, api local
http://localhost:7165/
client local, api remote
http://localhost:7165/?environment=production
client remote, api local
https://ga-wdi-boston.github.io/browser-template/?environment=development
This will require allowing "unsafe scripts" in Chrome
client remote, api remote
https://ga-wdi-boston.github.io/browser-template/
*/

const setAPIOrigin = (location, config) => {
// strip the leading `'?'`
const search = parseNestedQuery(location.search.slice(1));

if (search.environment === 'development' ||
location.hostname === 'localhost' &&
search.environment !== 'production') {
if (!(config.apiOrigin = config.apiOrigins.development)) {
let port = +('GA'.split('').reduce((p, c) =>
p + c.charCodeAt().toString(16), '')
);
config.apiOrigin = `http://localhost:${port}`;
}
} else {
config.apiOrigin = config.apiOrigins.production;
}
};

module.exports = setAPIOrigin;
Loading

0 comments on commit 7d3a6c0

Please sign in to comment.