Commit bd96d0fa authored by Sindre Sorhus's avatar Sindre Sorhus

Merge pull request #1182 from chrisprice/closure-app-upgrade-squashed

Closure app upgrade to new UI
parents 0a22d703 f119e6b9
node_modules/.bin
node_modules/plovr
node_modules/todomvc-app-css/*
!node_modules/todomvc-app-css/index.css
node_modules/todomvc-common/*
!node_modules/todomvc-common/base.css
!node_modules/todomvc-common/base.js
{
"name": "todomvc-closure",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.3.0"
}
}
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
<html lang="en" data-framework="closure"> <html lang="en" data-framework="closure">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Closure • TodoMVC</title> <title>Closure • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css"> <link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
</head> </head>
<body> <body>
<section id="todoapp"> <section id="todoapp">
...@@ -36,12 +38,12 @@ ...@@ -36,12 +38,12 @@
<p>Created by <a href="http://www.scottlogic.co.uk/blog/chris/">Chris Price</a></p> <p>Created by <a href="http://www.scottlogic.co.uk/blog/chris/">Chris Price</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer> </footer>
<script src="bower_components/todomvc-common/base.js"></script> <script src="node_modules/todomvc-common/base.js"></script>
<!-- The compiled version (to update run java -jar build/plovr.jar build plovr.json > js/compiled.js) --> <!-- The compiled version (see readme.md) -->
<script type="text/javascript" src="js/compiled.js"></script> <script type="text/javascript" src="js/compiled.js"></script>
<!-- The RAW development version (to serve the files run java -jar build/plovr.jar serve plovr.json) --> <!-- The RAW development version (see readme.md) -->
<!-- <script type="text/javascript" src="http://localhost:9810/compile?id=todomvc&mode=RAW"></script> --> <!--<script type="text/javascript" src="http://localhost:9810/compile?id=todomvc&mode=RAW"></script>-->
<!-- The COMPILED development version (to serve the files run java -jar build/plovr.jar serve plovr.json) --> <!-- The COMPILED development version (see readme.md) -->
<!-- <script type="text/javascript" src="http://localhost:9810/compile?id=todomvc&mode=ADVANCED"></script> --> <!-- <script type="text/javascript" src="http://localhost:9810/compile?id=todomvc&mode=ADVANCED"></script> -->
</body> </body>
</html> </html>
...@@ -29,8 +29,7 @@ goog.require('todomvc.view.ToDoListContainer'); ...@@ -29,8 +29,7 @@ goog.require('todomvc.view.ToDoListContainer');
* @type {todomvc.model.ToDoItemStore} * @type {todomvc.model.ToDoItemStore}
*/ */
var itemStore = new todomvc.model.ToDoItemStore(); var itemStore = new todomvc.model.ToDoItemStore();
itemStore.addEventListener(todomvc.model.ToDoItemStore.ChangeEventType, itemStore.listen(todomvc.model.ToDoItemStore.ChangeEventType, redraw);
redraw);
/** /**
* @type {todomvc.view.ToDoListContainer} * @type {todomvc.view.ToDoListContainer}
...@@ -110,8 +109,8 @@ var currentRoute = todomvc.Route.ALL; ...@@ -110,8 +109,8 @@ var currentRoute = todomvc.Route.ALL;
/** /**
* @type {!goog.History} * @type {!goog.History}
*/ */
var history = new goog.History(); var historyObj = new goog.History();
goog.events.listen(history, goog.history.EventType.NAVIGATE, goog.events.listen(historyObj, goog.history.EventType.NAVIGATE,
function(e) { function(e) {
// constrain the route to be one of the enum values // constrain the route to be one of the enum values
switch (e.token) { switch (e.token) {
...@@ -124,7 +123,7 @@ goog.events.listen(history, goog.history.EventType.NAVIGATE, ...@@ -124,7 +123,7 @@ goog.events.listen(history, goog.history.EventType.NAVIGATE,
} }
break; break;
default: default:
history.replaceToken(todomvc.Route.ALL); historyObj.replaceToken(todomvc.Route.ALL);
break; break;
} }
}); });
...@@ -163,14 +162,13 @@ function redraw() { ...@@ -163,14 +162,13 @@ function redraw() {
itemCountControl.setContent(remainingCount.toString()); itemCountControl.setContent(remainingCount.toString());
clearCompletedControl.setContent(doneCount.toString()); clearCompletedControl.setContent(doneCount.toString());
clearCompletedControl.setVisible(doneCount > 0); clearCompletedControl.setVisible(doneCount > 0);
goog.style.showElement(main, items.length > 0); goog.style.setElementShown(main, items.length > 0);
goog.style.showElement(footer, items.length > 0); goog.style.setElementShown(footer, items.length > 0);
/** /**
* @type {Array.<Element>} * @type {NodeList}
*/ */
var routeLinks = /** @type {Array.<Element>} */ var routeLinks = document.querySelectorAll('#filters a');
(goog.dom.query('#filters a'));
goog.array.forEach(routeLinks, function(link, i) { goog.array.forEach(routeLinks, function(link, i) {
if ((currentRoute === todomvc.Route.ALL && i === 0) || if ((currentRoute === todomvc.Route.ALL && i === 0) ||
(currentRoute === todomvc.Route.ACTIVE && i === 1) || (currentRoute === todomvc.Route.ACTIVE && i === 1) ||
...@@ -199,8 +197,8 @@ goog.events.listen(container, ...@@ -199,8 +197,8 @@ goog.events.listen(container,
* @type {!todomvc.model.ToDoItem} * @type {!todomvc.model.ToDoItem}
*/ */
var updatedModel = new todomvc.model.ToDoItem( var updatedModel = new todomvc.model.ToDoItem(
(/**@type {!string} */ control.getContent()), /**@type {!string} */ (control.getContent()),
(/**@type {!boolean} */ control.isChecked()), /**@type {!boolean} */ (control.isChecked()),
originalModel.getId()); originalModel.getId());
itemStore.addOrUpdate(updatedModel); itemStore.addOrUpdate(updatedModel);
...@@ -216,7 +214,7 @@ goog.events.listen(container, ...@@ -216,7 +214,7 @@ goog.events.listen(container,
/** /**
* @type {todomvc.model.ToDoItem} * @type {todomvc.model.ToDoItem}
*/ */
var model = (/**@type {todomvc.model.ToDoItem} */ control.getModel()); var model = /**@type {todomvc.model.ToDoItem} */ (control.getModel());
if (model !== null) { if (model !== null) {
itemStore.remove(model); itemStore.remove(model);
} }
...@@ -242,4 +240,4 @@ goog.events.listen(newToDo, goog.events.EventType.KEYUP, function(e) { ...@@ -242,4 +240,4 @@ goog.events.listen(newToDo, goog.events.EventType.KEYUP, function(e) {
}); });
itemStore.load(); itemStore.load();
history.setEnabled(true); historyObj.setEnabled(true);
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -16,6 +16,8 @@ goog.require('todomvc.model.ToDoItem'); ...@@ -16,6 +16,8 @@ goog.require('todomvc.model.ToDoItem');
* @extends {goog.events.EventTarget} * @extends {goog.events.EventTarget}
*/ */
todomvc.model.ToDoItemStore = function() { todomvc.model.ToDoItemStore = function() {
goog.events.EventTarget.call(this);
var mechanism = goog.storage.mechanism.mechanismfactory var mechanism = goog.storage.mechanism.mechanismfactory
.createHTML5LocalStorage(); .createHTML5LocalStorage();
/** /**
......
...@@ -25,10 +25,11 @@ goog.addSingletonGetter(todomvc.view.ClearCompletedControlRenderer); ...@@ -25,10 +25,11 @@ goog.addSingletonGetter(todomvc.view.ClearCompletedControlRenderer);
*/ */
todomvc.view.ClearCompletedControlRenderer.prototype.createDom = todomvc.view.ClearCompletedControlRenderer.prototype.createDom =
function(control) { function(control) {
var html = todomvc.view.clearCompleted({ var sanitizedHtml = todomvc.view.clearCompleted({
number: control.getContent() number: control.getContent()
}); });
var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html)); var element = /**@type {!Element}*/ (goog.dom.htmlToDocumentFragment(
sanitizedHtml.toString()));
this.setAriaStates(control, element); this.setAriaStates(control, element);
return element; return element;
}; };
......
...@@ -23,10 +23,11 @@ goog.addSingletonGetter(todomvc.view.ItemCountControlRenderer); ...@@ -23,10 +23,11 @@ goog.addSingletonGetter(todomvc.view.ItemCountControlRenderer);
* @return {Element} Root element for the control. * @return {Element} Root element for the control.
*/ */
todomvc.view.ItemCountControlRenderer.prototype.createDom = function(control) { todomvc.view.ItemCountControlRenderer.prototype.createDom = function(control) {
var html = todomvc.view.itemCount({ var sanitizedHtml = todomvc.view.itemCount({
number: control.getContent() number: control.getContent()
}); });
var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html)); var element = /**@type {!Element}*/ (goog.dom.htmlToDocumentFragment(
sanitizedHtml.toString()));
this.setAriaStates(control, element); this.setAriaStates(control, element);
return element; return element;
}; };
......
...@@ -71,8 +71,19 @@ todomvc.view.ToDoItemControl.prototype.enterDocument = function() { ...@@ -71,8 +71,19 @@ todomvc.view.ToDoItemControl.prototype.enterDocument = function() {
this.getHandler().listen(inputElement, goog.events.EventType.KEYUP, this.getHandler().listen(inputElement, goog.events.EventType.KEYUP,
function(e) { function(e) {
var be = e.getBrowserEvent(); var be = e.getBrowserEvent();
if (be.keyCode === goog.events.KeyCodes.ENTER) { switch (be.keyCode) {
this.setFocused(false); case goog.events.KeyCodes.ENTER:
this.setFocused(false);
break;
case goog.events.KeyCodes.ESC:
/**
* @type {Element}
*/
var inputElement = this.getRenderer().getInputElement(
this.getElement());
inputElement.value = this.getContent();
this.setFocused(false);
break;
} }
}); });
}; };
...@@ -85,7 +96,8 @@ todomvc.view.ToDoItemControl.prototype.enterDocument = function() { ...@@ -85,7 +96,8 @@ todomvc.view.ToDoItemControl.prototype.enterDocument = function() {
* component. * component.
*/ */
todomvc.view.ToDoItemControl.prototype.getRenderer = function() { todomvc.view.ToDoItemControl.prototype.getRenderer = function() {
return (/**@type {todomvc.view.ToDoItemControlRenderer}*/ this.renderer_); return /**@type {todomvc.view.ToDoItemControlRenderer}*/ (
this.getRenderer());
}; };
/** /**
......
...@@ -23,11 +23,12 @@ goog.addSingletonGetter(todomvc.view.ToDoItemControlRenderer); ...@@ -23,11 +23,12 @@ goog.addSingletonGetter(todomvc.view.ToDoItemControlRenderer);
* @return {Element} Root element for the control. * @return {Element} Root element for the control.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.createDom = function(control) { todomvc.view.ToDoItemControlRenderer.prototype.createDom = function(control) {
var html = todomvc.view.toDoItem({ var sanitizedHtml = todomvc.view.toDoItem({
content: control.getContent(), content: control.getContent(),
checked: control.isChecked() checked: control.isChecked()
}); });
var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html)); var element = /**@type {!Element}*/ (goog.dom.htmlToDocumentFragment(
sanitizedHtml.toString()));
this.setAriaStates(control, element); this.setAriaStates(control, element);
this.setState(control, /** @type {goog.ui.Component.State} */ this.setState(control, /** @type {goog.ui.Component.State} */
(control.getState()), true); (control.getState()), true);
......
...@@ -31,7 +31,7 @@ goog.inherits(todomvc.view.ToDoListContainer, goog.ui.Container); ...@@ -31,7 +31,7 @@ goog.inherits(todomvc.view.ToDoListContainer, goog.ui.Container);
* @param {goog.events.BrowserEvent} e Mousedown event to handle. * @param {goog.events.BrowserEvent} e Mousedown event to handle.
*/ */
todomvc.view.ToDoListContainer.prototype.handleMouseDown = function(e) { todomvc.view.ToDoListContainer.prototype.handleMouseDown = function(e) {
if (this.enabled_) { if (this.isEnabled()) {
this.setMouseButtonPressed(true); this.setMouseButtonPressed(true);
} }
}; };
...@@ -34,11 +34,11 @@ todomvc.view.ToDoListContainerRenderer.prototype.canDecorate = ...@@ -34,11 +34,11 @@ todomvc.view.ToDoListContainerRenderer.prototype.canDecorate =
*/ */
todomvc.view.ToDoListContainerRenderer.prototype.initializeDom = todomvc.view.ToDoListContainerRenderer.prototype.initializeDom =
function(container) { function(container) {
var elem = (/**@type {!Element}*/ container.getElement()); var elem = /**@type {!Element}*/ (container.getElement());
// Set the ARIA role. // Set the ARIA role.
var ariaRole = this.getAriaRole(); var ariaRole = this.getAriaRole();
if (ariaRole) { if (ariaRole) {
goog.dom.a11y.setRole(elem, ariaRole); goog.a11y.aria.setRole(elem, ariaRole);
} }
}; };
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #c5c5c5;
border-bottom: 1px dashed #f7f7f7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
#issue-count {
display: none;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
transition-property: left;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
padding-left: 300px;
}
.learn-bar > .learn {
left: 8px;
}
}
/* global _ */
(function () { (function () {
'use strict'; 'use strict';
/* jshint ignore:start */
// Underscore's Template Module // Underscore's Template Module
// Courtesy of underscorejs.org // Courtesy of underscorejs.org
var _ = (function (_) { var _ = (function (_) {
...@@ -114,6 +116,7 @@ ...@@ -114,6 +116,7 @@
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
/* jshint ignore:end */
function redirect() { function redirect() {
if (location.hostname === 'tastejs.github.io') { if (location.hostname === 'tastejs.github.io') {
...@@ -175,13 +178,17 @@ ...@@ -175,13 +178,17 @@
if (learnJSON.backend) { if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend; this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({ this.append({
backend: true backend: true
}); });
} else if (learnJSON[framework]) { } else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework]; this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append(); this.append();
} }
this.fetchIssueCount();
} }
Learn.prototype.append = function (opts) { Learn.prototype.append = function (opts) {
...@@ -212,6 +219,26 @@ ...@@ -212,6 +219,26 @@
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
}; };
Learn.prototype.fetchIssueCount = function () {
var issueLink = document.getElementById('issue-count-link');
if (issueLink) {
var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var parsedResponse = JSON.parse(e.target.responseText);
if (parsedResponse instanceof Array) {
var count = parsedResponse.length
if (count !== 0) {
issueLink.innerHTML = 'This app has ' + count + ' open issues';
document.getElementById('issue-count').style.display = 'inline';
}
}
};
xhr.send();
}
};
redirect(); redirect();
getFile('learn.json', Learn); getFile('learn.json', Learn);
})(); })();
{
"private": true,
"dependencies": {
"todomvc-app-css": "^1.0.0",
"todomvc-common": "^1.0.1"
},
"devDependencies": {
"plovr": "^3.0.0"
},
"scripts": {
"serve": "plovr serve plovr.json",
"build": "plovr build plovr.json > js/compiled.js"
}
}
...@@ -37,9 +37,10 @@ Note this project breaks with the convention of the others and uses spaces in pl ...@@ -37,9 +37,10 @@ Note this project breaks with the convention of the others and uses spaces in pl
## Running ## Running
A third party build tool called [Plovr](http://plovr.com/) is used to make running and compiling the code easier. To serve the code for development purposes (the example should run in compiled mode without using Plovr), first download the latest stable version from the [Plovr Google Code project](http://code.google.com/p/plovr/downloads/list) (at the time of writing plovr-eba786b34df9.jar). Copy the file into the build folder, rename it plovr.jar and run the following command from this folder - A third party build tool called [Plovr](http://plovr.com/) is used to make running and compiling the code easier. To serve the code for development purposes (the example should run in compiled mode without using Plovr), run the following command from this folder -
`java -jar build/plovr.jar serve plovr.json` `npm install`
`npm run serve`
You'll also need to change the HTML file so that it references the served files instead of the compiled version (**make sure you comment out the compiled version otherwise it will not work**), to do this remove the compiled script reference and add the following - You'll also need to change the HTML file so that it references the served files instead of the compiled version (**make sure you comment out the compiled version otherwise it will not work**), to do this remove the compiled script reference and add the following -
...@@ -56,16 +57,17 @@ Whilst Plovr features many of the tools from the Closure toolkit, one very usefu ...@@ -56,16 +57,17 @@ Whilst Plovr features many of the tools from the Closure toolkit, one very usefu
The linter must be installed before use, the installation package is included in the build folder and the instructions are available on the [linter homepage](https://developers.google.com/closure/utilities/). Once installed run the following to check for errors - The linter must be installed before use, the installation package is included in the build folder and the instructions are available on the [linter homepage](https://developers.google.com/closure/utilities/). Once installed run the following to check for errors -
`find . -name *.js | xargs gjslint` `find . -path ./node_modules -prune -o -name *.js | xargs gjslint`
(or whatever floats your OSs boat) (or whatever floats your OSs boat)
## Compiling ## Compiling
To compile the code from the command line run Plovr like so - To compile the code from the command line run -
`java -jar build/plovr.jar build plovr.json > js/compiled.js` `npm install`
`npm run build`
This will overwrite the js/compiled.js file with the new version, be sure to change the script tag reference in the HTML page. This will overwrite the js/compiled.js file with the new version, be sure to change the script tag reference in the HTML page.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment