Commit 3d71ff07 authored by Sindre Sorhus's avatar Sindre Sorhus

Fixed crlf issue

parent 9e536a3c
This diff is collapsed.
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.events.EventType'); goog.require('goog.events.EventType');
goog.require('goog.events.KeyCodes'); goog.require('goog.events.KeyCodes');
goog.require('goog.ui.Component'); goog.require('goog.ui.Component');
goog.require('goog.ui.Control'); goog.require('goog.ui.Control');
goog.require('todomvc.model.ToDoItem'); goog.require('todomvc.model.ToDoItem');
goog.require('todomvc.view'); goog.require('todomvc.view');
goog.require('todomvc.view.ClearCompletedControlRenderer'); goog.require('todomvc.view.ClearCompletedControlRenderer');
goog.require('todomvc.view.ItemCountControlRenderer'); goog.require('todomvc.view.ItemCountControlRenderer');
goog.require('todomvc.view.ToDoItemControl'); goog.require('todomvc.view.ToDoItemControl');
goog.require('todomvc.view.ToDoListContainer'); goog.require('todomvc.view.ToDoListContainer');
/** /**
* @fileoverview The controller/business logic for the application. * @fileoverview The controller/business logic for the application.
* *
* This file creates the interface and marshalls changes from the interface to the model and back. * This file creates the interface and marshalls changes from the interface to the model and back.
*/ */
/** /**
* @type {Array.<todomvc.model.ToDoItem>} * @type {Array.<todomvc.model.ToDoItem>}
*/ */
var items = []; var items = [];
/** /**
* @type {Element} * @type {Element}
*/ */
var todoStats = document.getElementById('todo-stats'); var todoStats = document.getElementById('todo-stats');
/** /**
* @type {goog.ui.Control} * @type {goog.ui.Control}
*/ */
var itemCountControl = new goog.ui.Control(null, todomvc.view.ItemCountControlRenderer.getInstance()); var itemCountControl = new goog.ui.Control(null, todomvc.view.ItemCountControlRenderer.getInstance());
itemCountControl.render(todoStats); itemCountControl.render(todoStats);
/** /**
* @type {goog.ui.Control} * @type {goog.ui.Control}
*/ */
var clearCompletedControl = new goog.ui.Control(null, todomvc.view.ClearCompletedControlRenderer.getInstance()); var clearCompletedControl = new goog.ui.Control(null, todomvc.view.ClearCompletedControlRenderer.getInstance());
clearCompletedControl.render(todoStats); clearCompletedControl.render(todoStats);
goog.events.listen(clearCompletedControl, goog.ui.Component.EventType.ACTION, function(e) { goog.events.listen(clearCompletedControl, goog.ui.Component.EventType.ACTION, function(e) {
// go backwards to avoid collection modification problems // go backwards to avoid collection modification problems
goog.array.forEachRight(items, function(model) { goog.array.forEachRight(items, function(model) {
if (model.isDone()) { if (model.isDone()) {
goog.array.remove(items, model); goog.array.remove(items, model);
// do optimised model view sync // do optimised model view sync
container.forEachChild(function(control) { container.forEachChild(function(control) {
if (control.getModel() === model) { if (control.getModel() === model) {
container.removeChild(control, true); container.removeChild(control, true);
} }
}); });
} }
}); });
updateStats(); updateStats();
}); });
function updateStats() { function updateStats() {
var doneCount = goog.array.reduce(items, function(count, model) { var doneCount = goog.array.reduce(items, function(count, model) {
return model.isDone() ? count + 1 : count; return model.isDone() ? count + 1 : count;
}, 0); }, 0);
var remainingCount = items.length - (/**@type {number}*/ doneCount); var remainingCount = items.length - (/**@type {number}*/ doneCount);
itemCountControl.setContent((/**@type {string}*/ remainingCount)); itemCountControl.setContent((/**@type {string}*/ remainingCount));
itemCountControl.setVisible(remainingCount > 0); itemCountControl.setVisible(remainingCount > 0);
clearCompletedControl.setContent((/**@type {string}*/ doneCount)); clearCompletedControl.setContent((/**@type {string}*/ doneCount));
clearCompletedControl.setVisible((/**@type {number}*/ doneCount) > 0); clearCompletedControl.setVisible((/**@type {number}*/ doneCount) > 0);
} }
updateStats(); updateStats();
/** /**
* @type {todomvc.view.ToDoListContainer} * @type {todomvc.view.ToDoListContainer}
*/ */
var container = new todomvc.view.ToDoListContainer(); var container = new todomvc.view.ToDoListContainer();
container.decorate(document.getElementById('todo-list')); container.decorate(document.getElementById('todo-list'));
goog.events.listen(container, todomvc.view.ToDoItemControl.EventType.EDIT, function(e) { goog.events.listen(container, todomvc.view.ToDoItemControl.EventType.EDIT, function(e) {
/** /**
* @type {todomvc.view.ToDoItemControl} * @type {todomvc.view.ToDoItemControl}
*/ */
var control = e.target; var control = e.target;
/** /**
* @type {todomvc.model.ToDoItem} * @type {todomvc.model.ToDoItem}
*/ */
var model = (/**@type {todomvc.model.ToDoItem} */ control.getModel()); var model = (/**@type {todomvc.model.ToDoItem} */ control.getModel());
// do optimised model view sync // do optimised model view sync
model.setNote((/**@type {!string} */ control.getContent())); model.setNote((/**@type {!string} */ control.getContent()));
model.setDone((/**@type {!boolean} */ control.isChecked())); model.setDone((/**@type {!boolean} */ control.isChecked()));
updateStats(); updateStats();
}); });
goog.events.listen(container, todomvc.view.ToDoItemControl.EventType.DESTROY, function(e) { goog.events.listen(container, todomvc.view.ToDoItemControl.EventType.DESTROY, function(e) {
/** /**
* @type {todomvc.view.ToDoItemControl} * @type {todomvc.view.ToDoItemControl}
*/ */
var control = e.target; var control = e.target;
/** /**
* @type {todomvc.model.ToDoItem} * @type {todomvc.model.ToDoItem}
*/ */
var model = (/**@type {todomvc.model.ToDoItem} */ control.getModel()); var model = (/**@type {todomvc.model.ToDoItem} */ control.getModel());
// do optimised model view sync // do optimised model view sync
goog.array.remove(items, model); goog.array.remove(items, model);
container.removeChild(control, true); container.removeChild(control, true);
updateStats(); updateStats();
}); });
/** /**
* @type {Element} * @type {Element}
*/ */
var newToDo = document.getElementById('new-todo'); var newToDo = document.getElementById('new-todo');
goog.events.listen(newToDo, goog.events.EventType.KEYUP, function(e) { goog.events.listen(newToDo, goog.events.EventType.KEYUP, function(e) {
if (e.keyCode === goog.events.KeyCodes.ENTER) { if (e.keyCode === goog.events.KeyCodes.ENTER) {
/** /**
* @type {todomvc.model.ToDoItem} * @type {todomvc.model.ToDoItem}
*/ */
var model = new todomvc.model.ToDoItem(newToDo.value); var model = new todomvc.model.ToDoItem(newToDo.value);
/** /**
* @type {todomvc.view.ToDoItemControl} * @type {todomvc.view.ToDoItemControl}
*/ */
var control = new todomvc.view.ToDoItemControl(); var control = new todomvc.view.ToDoItemControl();
// do optimised model view sync // do optimised model view sync
items.push(model); items.push(model);
control.setContent(model.getNote()); control.setContent(model.getNote());
control.setChecked(model.isDone()); control.setChecked(model.isDone());
control.setModel(model); control.setModel(model);
container.addChild(control, true); container.addChild(control, true);
// clear the input box // clear the input box
newToDo.value = ''; newToDo.value = '';
updateStats(); updateStats();
} }
}); });
\ No newline at end of file
goog.provide('todomvc.model.ToDoItem'); goog.provide('todomvc.model.ToDoItem');
/** /**
* The model object representing a todo item. * The model object representing a todo item.
* *
* @param {!string} note the text associated with this item * @param {!string} note the text associated with this item
* @param {!boolean=} opt_done is this item complete? defaults to false * @param {!boolean=} opt_done is this item complete? defaults to false
* @constructor * @constructor
*/ */
todomvc.model.ToDoItem = function(note, opt_done) { todomvc.model.ToDoItem = function(note, opt_done) {
/** /**
* note the text associated with this item * note the text associated with this item
* @private * @private
* @type {!string} * @type {!string}
*/ */
this.note_ = note; this.note_ = note;
/** /**
* is this item complete? * is this item complete?
* @private * @private
* @type {!boolean} * @type {!boolean}
*/ */
this.done_ = opt_done || false; this.done_ = opt_done || false;
}; };
/** /**
* @return {!string} the text associated with this item * @return {!string} the text associated with this item
*/ */
todomvc.model.ToDoItem.prototype.getNote = function() { todomvc.model.ToDoItem.prototype.getNote = function() {
return this.note_; return this.note_;
}; };
/** /**
* @return {!boolean} is this item complete? * @return {!boolean} is this item complete?
*/ */
todomvc.model.ToDoItem.prototype.isDone = function() { todomvc.model.ToDoItem.prototype.isDone = function() {
return this.done_; return this.done_;
}; };
/** /**
* @param {!string} note the text associated with this item * @param {!string} note the text associated with this item
*/ */
todomvc.model.ToDoItem.prototype.setNote = function(note) { todomvc.model.ToDoItem.prototype.setNote = function(note) {
this.note_ = note; this.note_ = note;
}; };
/** /**
* @param {!boolean} done is this item complete? * @param {!boolean} done is this item complete?
*/ */
todomvc.model.ToDoItem.prototype.setDone = function(done) { todomvc.model.ToDoItem.prototype.setDone = function(done) {
this.done_ = done; this.done_ = done;
}; };
\ No newline at end of file
goog.provide('todomvc.view.ClearCompletedControlRenderer'); goog.provide('todomvc.view.ClearCompletedControlRenderer');
goog.require('goog.dom'); goog.require('goog.dom');
goog.require('goog.ui.Component.State'); goog.require('goog.ui.Component.State');
goog.require('goog.ui.ControlRenderer'); goog.require('goog.ui.ControlRenderer');
/** /**
* A renderer for the clear completed control. * A renderer for the clear completed control.
* *
* @constructor * @constructor
* @extends {goog.ui.ControlRenderer} * @extends {goog.ui.ControlRenderer}
*/ */
todomvc.view.ClearCompletedControlRenderer = function() { todomvc.view.ClearCompletedControlRenderer = function() {
goog.ui.ControlRenderer.call(this); goog.ui.ControlRenderer.call(this);
}; };
goog.inherits(todomvc.view.ClearCompletedControlRenderer, goog.ui.ControlRenderer); goog.inherits(todomvc.view.ClearCompletedControlRenderer, goog.ui.ControlRenderer);
// add getInstance method to todomvc.view.ClearCompletedControlRenderer // add getInstance method to todomvc.view.ClearCompletedControlRenderer
goog.addSingletonGetter(todomvc.view.ClearCompletedControlRenderer); goog.addSingletonGetter(todomvc.view.ClearCompletedControlRenderer);
/** /**
* @param {goog.ui.Control} control Control to render. * @param {goog.ui.Control} control Control to render.
* @return {Element} Root element for the control. * @return {Element} Root element for the control.
*/ */
todomvc.view.ClearCompletedControlRenderer.prototype.createDom = function(control) { todomvc.view.ClearCompletedControlRenderer.prototype.createDom = function(control) {
var html = todomvc.view.clearCompleted({ var html = todomvc.view.clearCompleted({
number : control.getContent() number : control.getContent()
}); });
var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html)); var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html));
this.setAriaStates(control, element); this.setAriaStates(control, element);
return element; return element;
}; };
/** /**
* @param {Element} element Element to decorate. * @param {Element} element Element to decorate.
* @return {boolean} Whether the renderer can decorate the element. * @return {boolean} Whether the renderer can decorate the element.
*/ */
todomvc.view.ClearCompletedControlRenderer.prototype.canDecorate = function(element) { todomvc.view.ClearCompletedControlRenderer.prototype.canDecorate = function(element) {
return false; return false;
}; };
/** /**
* @param {Element} element Element to populate. * @param {Element} element Element to populate.
* @param {goog.ui.ControlContent} content Text caption or DOM * @param {goog.ui.ControlContent} content Text caption or DOM
*/ */
todomvc.view.ClearCompletedControlRenderer.prototype.setContent = function(element, content) { todomvc.view.ClearCompletedControlRenderer.prototype.setContent = function(element, content) {
element.innerHTML = todomvc.view.clearCompletedInner({ element.innerHTML = todomvc.view.clearCompletedInner({
number : content number : content
}); });
}; };
/** /**
* Updates the appearance of the control in response to a state change. * Updates the appearance of the control in response to a state change.
* *
* @param {goog.ui.Control} control Control instance to update. * @param {goog.ui.Control} control Control instance to update.
* @param {goog.ui.Component.State} state State to enable or disable. * @param {goog.ui.Component.State} state State to enable or disable.
* @param {boolean} enable Whether the control is entering or exiting the state. * @param {boolean} enable Whether the control is entering or exiting the state.
*/ */
todomvc.view.ClearCompletedControlRenderer.prototype.setState = function(control, state, enable) { todomvc.view.ClearCompletedControlRenderer.prototype.setState = function(control, state, enable) {
var element = control.getElement(); var element = control.getElement();
if (element) { if (element) {
this.updateAriaState(element, state, enable); this.updateAriaState(element, state, enable);
} }
}; };
goog.provide('todomvc.view.ItemCountControlRenderer'); goog.provide('todomvc.view.ItemCountControlRenderer');
goog.require('goog.dom'); goog.require('goog.dom');
goog.require('goog.ui.Component.State'); goog.require('goog.ui.Component.State');
goog.require('goog.ui.ControlRenderer'); goog.require('goog.ui.ControlRenderer');
/** /**
* A renderer for the item count control. * A renderer for the item count control.
* *
* @constructor * @constructor
* @extends {goog.ui.ControlRenderer} * @extends {goog.ui.ControlRenderer}
*/ */
todomvc.view.ItemCountControlRenderer = function() { todomvc.view.ItemCountControlRenderer = function() {
goog.ui.ControlRenderer.call(this); goog.ui.ControlRenderer.call(this);
}; };
goog.inherits(todomvc.view.ItemCountControlRenderer, goog.ui.ControlRenderer); goog.inherits(todomvc.view.ItemCountControlRenderer, goog.ui.ControlRenderer);
// add getInstance method to todomvc.view.ItemCountControlRenderer // add getInstance method to todomvc.view.ItemCountControlRenderer
goog.addSingletonGetter(todomvc.view.ItemCountControlRenderer); goog.addSingletonGetter(todomvc.view.ItemCountControlRenderer);
/** /**
* @param {goog.ui.Control} control Control to render. * @param {goog.ui.Control} control Control to render.
* @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 html = todomvc.view.itemCount({
number : control.getContent() number : control.getContent()
}); });
var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html)); var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html));
this.setAriaStates(control, element); this.setAriaStates(control, element);
return element; return element;
}; };
/** /**
* @param {Element} element Element to decorate. * @param {Element} element Element to decorate.
* @return {boolean} Whether the renderer can decorate the element. * @return {boolean} Whether the renderer can decorate the element.
*/ */
todomvc.view.ItemCountControlRenderer.prototype.canDecorate = function(element) { todomvc.view.ItemCountControlRenderer.prototype.canDecorate = function(element) {
return false; return false;
}; };
/** /**
* @param {Element} element Element to populate. * @param {Element} element Element to populate.
* @param {goog.ui.ControlContent} content Text caption or DOM * @param {goog.ui.ControlContent} content Text caption or DOM
*/ */
todomvc.view.ItemCountControlRenderer.prototype.setContent = function(element, content) { todomvc.view.ItemCountControlRenderer.prototype.setContent = function(element, content) {
element.innerHTML = todomvc.view.itemCountInner({ element.innerHTML = todomvc.view.itemCountInner({
number : content number : content
}); });
}; };
/** /**
* Updates the appearance of the control in response to a state change. * Updates the appearance of the control in response to a state change.
* *
* @param {goog.ui.Control} control Control instance to update. * @param {goog.ui.Control} control Control instance to update.
* @param {goog.ui.Component.State} state State to enable or disable. * @param {goog.ui.Component.State} state State to enable or disable.
* @param {boolean} enable Whether the control is entering or exiting the state. * @param {boolean} enable Whether the control is entering or exiting the state.
*/ */
todomvc.view.ItemCountControlRenderer.prototype.setState = function(control, state, enable) { todomvc.view.ItemCountControlRenderer.prototype.setState = function(control, state, enable) {
var element = control.getElement(); var element = control.getElement();
if (element) { if (element) {
this.updateAriaState(element, state, enable); this.updateAriaState(element, state, enable);
} }
}; };
goog.provide('todomvc.view.ToDoItemControl'); goog.provide('todomvc.view.ToDoItemControl');
goog.require('goog.dom'); goog.require('goog.dom');
goog.require('goog.events'); goog.require('goog.events');
goog.require('goog.ui.Component.State'); goog.require('goog.ui.Component.State');
goog.require('goog.ui.Control'); goog.require('goog.ui.Control');
goog.require('todomvc.view.ToDoItemControlRenderer'); goog.require('todomvc.view.ToDoItemControlRenderer');
/** /**
* A control representing each item in the todo list. It makes use of the CHECKED and SELECTED states to represent being * A control representing each item in the todo list. It makes use of the CHECKED and SELECTED states to represent being
* done and being in edit mode. * done and being in edit mode.
* *
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for document interaction. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for document interaction.
* @constructor * @constructor
* @extends {goog.ui.Control} * @extends {goog.ui.Control}
*/ */
todomvc.view.ToDoItemControl = function(opt_domHelper) { todomvc.view.ToDoItemControl = function(opt_domHelper) {
goog.ui.Control.call(this, "", todomvc.view.ToDoItemControlRenderer goog.ui.Control.call(this, "", todomvc.view.ToDoItemControlRenderer
.getInstance(), opt_domHelper); .getInstance(), opt_domHelper);
// enable CHECKED and SELECTED states // enable CHECKED and SELECTED states
this.setSupportedState(goog.ui.Component.State.CHECKED, true); this.setSupportedState(goog.ui.Component.State.CHECKED, true);
this.setSupportedState(goog.ui.Component.State.SELECTED, true); this.setSupportedState(goog.ui.Component.State.SELECTED, true);
// disable auto handling of CHECKED and SELECTED states // disable auto handling of CHECKED and SELECTED states
this.setAutoStates(goog.ui.Component.State.CHECKED, false); this.setAutoStates(goog.ui.Component.State.CHECKED, false);
this.setAutoStates(goog.ui.Component.State.SELECTED, false); this.setAutoStates(goog.ui.Component.State.SELECTED, false);
// allow text selection within this control // allow text selection within this control
this.setAllowTextSelection(true); this.setAllowTextSelection(true);
}; };
goog.inherits(todomvc.view.ToDoItemControl, goog.ui.Control); goog.inherits(todomvc.view.ToDoItemControl, goog.ui.Control);
todomvc.view.ToDoItemControl.EventType = { todomvc.view.ToDoItemControl.EventType = {
EDIT: "edit", EDIT: "edit",
DESTROY: "destroy" DESTROY: "destroy"
}; };
/** /**
* Configures the component after its DOM has been rendered, and sets up event * Configures the component after its DOM has been rendered, and sets up event
* handling. Overrides {@link goog.ui.Component#enterDocument}. * handling. Overrides {@link goog.ui.Component#enterDocument}.
* *
* @override * @override
*/ */
todomvc.view.ToDoItemControl.prototype.enterDocument = function() { todomvc.view.ToDoItemControl.prototype.enterDocument = function() {
todomvc.view.ToDoItemControl.superClass_.enterDocument.call(this); todomvc.view.ToDoItemControl.superClass_.enterDocument.call(this);
// prevent clicking the checkbox (or anything within the root element) // prevent clicking the checkbox (or anything within the root element)
// from having any default behaviour. This stops the checkbox being set // from having any default behaviour. This stops the checkbox being set
// by the browser. // by the browser.
this.getHandler().listen(this.getElement(), goog.events.EventType.CLICK, this.getHandler().listen(this.getElement(), goog.events.EventType.CLICK,
function(e) { function(e) {
e.preventDefault(); e.preventDefault();
}); });
}; };
/** /**
* Returns the renderer used by this component to render itself or to decorate * Returns the renderer used by this component to render itself or to decorate
* an existing element. * an existing element.
* *
* @return {todomvc.view.ToDoItemControlRenderer} Renderer used by the component * @return {todomvc.view.ToDoItemControlRenderer} Renderer used by the 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.renderer_);
}; };
/** /**
* Specialised handling of mouse events when clicking on the checkbox, label, * Specialised handling of mouse events when clicking on the checkbox, label,
* textbox or remove link. * textbox or remove link.
* *
* @param {goog.events.Event} e Mouse event to handle. * @param {goog.events.Event} e Mouse event to handle.
*/ */
todomvc.view.ToDoItemControl.prototype.handleMouseUp = function(e) { todomvc.view.ToDoItemControl.prototype.handleMouseUp = function(e) {
todomvc.view.ToDoItemControl.superClass_.handleMouseUp.call(this, e); todomvc.view.ToDoItemControl.superClass_.handleMouseUp.call(this, e);
if (this.isEnabled()) { if (this.isEnabled()) {
if (e.target === this.getRenderer().getCheckboxElement( if (e.target === this.getRenderer().getCheckboxElement(
this.getElement())) { this.getElement())) {
this.setChecked(!this.isChecked()); this.setChecked(!this.isChecked());
this.dispatchEvent(todomvc.view.ToDoItemControl.EventType.EDIT); this.dispatchEvent(todomvc.view.ToDoItemControl.EventType.EDIT);
} else if (e.target === this.getRenderer().getDestroyElement( } else if (e.target === this.getRenderer().getDestroyElement(
this.getElement())) { this.getElement())) {
this.dispatchEvent(todomvc.view.ToDoItemControl.EventType.DESTROY); this.dispatchEvent(todomvc.view.ToDoItemControl.EventType.DESTROY);
} else if (!this.isSelected()) { } else if (!this.isSelected()) {
this.setSelected(true); this.setSelected(true);
} }
} }
}; };
/** /**
* Override the behaviour when the control is unfocused. * Override the behaviour when the control is unfocused.
* @param {boolean} focused * @param {boolean} focused
*/ */
todomvc.view.ToDoItemControl.prototype.setFocused = function(focused) { todomvc.view.ToDoItemControl.prototype.setFocused = function(focused) {
todomvc.view.ToDoItemControl.superClass_.setFocused.call(this, focused); todomvc.view.ToDoItemControl.superClass_.setFocused.call(this, focused);
if (!focused && this.isSelected()) { if (!focused && this.isSelected()) {
/** /**
* @type {Element} * @type {Element}
*/ */
var inputElement = this.getRenderer().getInputElement( var inputElement = this.getRenderer().getInputElement(
this.getElement()); this.getElement());
this.setContent(inputElement.value); this.setContent(inputElement.value);
this.setSelected(false); this.setSelected(false);
this.dispatchEvent(todomvc.view.ToDoItemControl.EventType.EDIT); this.dispatchEvent(todomvc.view.ToDoItemControl.EventType.EDIT);
} }
}; };
/** /**
* Override the behaviour to switch to editing mode when the control is selected * Override the behaviour to switch to editing mode when the control is selected
* @param {boolean} selected * @param {boolean} selected
*/ */
todomvc.view.ToDoItemControl.prototype.setSelected = function(selected) { todomvc.view.ToDoItemControl.prototype.setSelected = function(selected) {
todomvc.view.ToDoItemControl.superClass_.setSelected.call(this, selected); todomvc.view.ToDoItemControl.superClass_.setSelected.call(this, selected);
if (selected) { if (selected) {
/** /**
* @type {Element} * @type {Element}
*/ */
var inputElement = this.getRenderer().getInputElement( var inputElement = this.getRenderer().getInputElement(
this.getElement()); this.getElement());
inputElement.value = this.getContent(); inputElement.value = this.getContent();
inputElement.focus(); inputElement.focus();
} }
}; };
\ No newline at end of file
goog.provide('todomvc.view.ToDoItemControlRenderer'); goog.provide('todomvc.view.ToDoItemControlRenderer');
goog.require('goog.ui.Component.State'); goog.require('goog.ui.Component.State');
goog.require('goog.ui.ControlRenderer'); goog.require('goog.ui.ControlRenderer');
/** /**
* The renderer for the ToDoItemControl which has knowledge of the DOM structure of the Control and the applicable CSS * The renderer for the ToDoItemControl which has knowledge of the DOM structure of the Control and the applicable CSS
* classes. * classes.
* *
* @constructor * @constructor
* @extends {goog.ui.ControlRenderer} * @extends {goog.ui.ControlRenderer}
*/ */
todomvc.view.ToDoItemControlRenderer = function() { todomvc.view.ToDoItemControlRenderer = function() {
goog.ui.ControlRenderer.call(this); goog.ui.ControlRenderer.call(this);
}; };
goog.inherits(todomvc.view.ToDoItemControlRenderer, goog.ui.ControlRenderer); goog.inherits(todomvc.view.ToDoItemControlRenderer, goog.ui.ControlRenderer);
// add getInstance method to todomvc.view.ToDoItemControlRenderer // add getInstance method to todomvc.view.ToDoItemControlRenderer
goog.addSingletonGetter(todomvc.view.ToDoItemControlRenderer); goog.addSingletonGetter(todomvc.view.ToDoItemControlRenderer);
/** /**
* @param {goog.ui.Control} control Control to render. * @param {goog.ui.Control} control Control to render.
* @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 html = todomvc.view.toDoItem({
content : control.getContent() content : control.getContent()
}); });
var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html)); var element = (/**@type {!Element}*/ goog.dom.htmlToDocumentFragment(html));
this.setAriaStates(control, element); this.setAriaStates(control, element);
return element; return element;
}; };
/** /**
* Updates the appearance of the control in response to a state change. * Updates the appearance of the control in response to a state change.
* *
* @param {goog.ui.Control} control Control instance to update. * @param {goog.ui.Control} control Control instance to update.
* @param {goog.ui.Component.State} state State to enable or disable. * @param {goog.ui.Component.State} state State to enable or disable.
* @param {boolean} enable Whether the control is entering or exiting the state. * @param {boolean} enable Whether the control is entering or exiting the state.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.setState = function(control, state, enable) { todomvc.view.ToDoItemControlRenderer.prototype.setState = function(control, state, enable) {
var element = control.getElement(); var element = control.getElement();
if (element) { if (element) {
switch (state) { switch (state) {
case goog.ui.Component.State.CHECKED: case goog.ui.Component.State.CHECKED:
this.enableClassName(control, "done", enable); this.enableClassName(control, "done", enable);
this.getCheckboxElement(element).checked = enable; this.getCheckboxElement(element).checked = enable;
break; break;
case goog.ui.Component.State.SELECTED: case goog.ui.Component.State.SELECTED:
this.enableClassName(control, "editing", enable); this.enableClassName(control, "editing", enable);
break; break;
} }
this.updateAriaState(element, state, enable); this.updateAriaState(element, state, enable);
} }
}; };
/** /**
* Returns the element within the component's DOM that should receive keyboard * Returns the element within the component's DOM that should receive keyboard
* focus (null if none). The default implementation returns the control's root * focus (null if none). The default implementation returns the control's root
* element. * element.
* @param {goog.ui.Control} control Control whose key event target is to be * @param {goog.ui.Control} control Control whose key event target is to be
* returned. * returned.
* @return {Element} The key event target. * @return {Element} The key event target.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.getKeyEventTarget = function(control) { todomvc.view.ToDoItemControlRenderer.prototype.getKeyEventTarget = function(control) {
return this.getInputElement(control.getElement()); return this.getInputElement(control.getElement());
}; };
/** /**
* Takes the control's root element and returns the display element * Takes the control's root element and returns the display element
* *
* @param {Element} element Root element of the control whose display element is * @param {Element} element Root element of the control whose display element is
* to be returned. * to be returned.
* @return {Element} The control's display element. * @return {Element} The control's display element.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.getDisplayElement = function( todomvc.view.ToDoItemControlRenderer.prototype.getDisplayElement = function(
element) { element) {
return element ? element.childNodes[0].childNodes[0] : null; return element ? element.childNodes[0].childNodes[0] : null;
}; };
/** /**
* Takes the control's root element and returns the parent element of the * Takes the control's root element and returns the parent element of the
* control's contents. * control's contents.
* *
* @param {Element} element Root element of the control whose content element is * @param {Element} element Root element of the control whose content element is
* to be returned. * to be returned.
* @return {Element} The control's content element. * @return {Element} The control's content element.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.getContentElement = function( todomvc.view.ToDoItemControlRenderer.prototype.getContentElement = function(
element) { element) {
return element ? this.getDisplayElement(element).childNodes[1] : null; return element ? this.getDisplayElement(element).childNodes[1] : null;
}; };
/** /**
* Takes the control's root element and returns the checkbox element * Takes the control's root element and returns the checkbox element
* *
* @param {Element} element Root element of the control whose checkbox element * @param {Element} element Root element of the control whose checkbox element
* is to be returned. * is to be returned.
* @return {Element} The control's checkbox element. * @return {Element} The control's checkbox element.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.getCheckboxElement = function( todomvc.view.ToDoItemControlRenderer.prototype.getCheckboxElement = function(
element) { element) {
return element ? this.getDisplayElement(element).childNodes[0] : null; return element ? this.getDisplayElement(element).childNodes[0] : null;
}; };
/** /**
* Takes the control's root element and returns the destroy element * Takes the control's root element and returns the destroy element
* *
* @param {Element} element Root element of the control whose destroy element is * @param {Element} element Root element of the control whose destroy element is
* to be returned. * to be returned.
* @return {Element} The control's destroy element. * @return {Element} The control's destroy element.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.getDestroyElement = function( todomvc.view.ToDoItemControlRenderer.prototype.getDestroyElement = function(
element) { element) {
return element ? this.getDisplayElement(element).childNodes[2] : null; return element ? this.getDisplayElement(element).childNodes[2] : null;
}; };
/** /**
* Takes the control's root element and returns the input element * Takes the control's root element and returns the input element
* *
* @param {Element} element Root element of the control whose input element is * @param {Element} element Root element of the control whose input element is
* to be returned. * to be returned.
* @return {Element} The control's input element. * @return {Element} The control's input element.
*/ */
todomvc.view.ToDoItemControlRenderer.prototype.getInputElement = function( todomvc.view.ToDoItemControlRenderer.prototype.getInputElement = function(
element) { element) {
return element ? element.childNodes[0].childNodes[1].childNodes[0] : null; return element ? element.childNodes[0].childNodes[1].childNodes[0] : null;
}; };
goog.provide('todomvc.view.ToDoListContainer'); goog.provide('todomvc.view.ToDoListContainer');
goog.require('goog.ui.Container'); goog.require('goog.ui.Container');
goog.require('todomvc.view.ToDoListContainerRenderer'); goog.require('todomvc.view.ToDoListContainerRenderer');
/** /**
* A container for the ToDoItemControls, overridden to support keyboard focus on child controls. * A container for the ToDoItemControls, overridden to support keyboard focus on child controls.
* *
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for document interaction. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for document interaction.
* @constructor * @constructor
* @extends {goog.ui.Container} * @extends {goog.ui.Container}
*/ */
todomvc.view.ToDoListContainer = function(opt_domHelper) { todomvc.view.ToDoListContainer = function(opt_domHelper) {
goog.ui.Container goog.ui.Container
.call(this, goog.ui.Container.Orientation.VERTICAL, .call(this, goog.ui.Container.Orientation.VERTICAL,
todomvc.view.ToDoListContainerRenderer.getInstance(), todomvc.view.ToDoListContainerRenderer.getInstance(),
opt_domHelper); opt_domHelper);
// allow focus on children // allow focus on children
this.setFocusable(false); this.setFocusable(false);
this.setFocusableChildrenAllowed(true); this.setFocusableChildrenAllowed(true);
}; };
goog.inherits(todomvc.view.ToDoListContainer, goog.ui.Container); goog.inherits(todomvc.view.ToDoListContainer, goog.ui.Container);
/** /**
* Override this method to allow text selection in children. * Override this method to allow text selection in children.
* *
* @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.enabled_) {
this.setMouseButtonPressed(true); this.setMouseButtonPressed(true);
} }
}; };
\ No newline at end of file
goog.provide('todomvc.view.ToDoListContainerRenderer'); goog.provide('todomvc.view.ToDoListContainerRenderer');
goog.require('goog.ui.Component.State'); goog.require('goog.ui.Component.State');
goog.require('goog.ui.Container'); goog.require('goog.ui.Container');
goog.require('goog.ui.ContainerRenderer'); goog.require('goog.ui.ContainerRenderer');
/** /**
* A renderer for the container, overridden to support keyboard focus on child controls. * A renderer for the container, overridden to support keyboard focus on child controls.
* @constructor * @constructor
* @extends {goog.ui.ContainerRenderer} * @extends {goog.ui.ContainerRenderer}
*/ */
todomvc.view.ToDoListContainerRenderer = function() { todomvc.view.ToDoListContainerRenderer = function() {
goog.ui.ContainerRenderer.call(this); goog.ui.ContainerRenderer.call(this);
}; };
goog.inherits(todomvc.view.ToDoListContainerRenderer, goog.inherits(todomvc.view.ToDoListContainerRenderer,
goog.ui.ContainerRenderer); goog.ui.ContainerRenderer);
goog.addSingletonGetter(todomvc.view.ToDoListContainerRenderer); goog.addSingletonGetter(todomvc.view.ToDoListContainerRenderer);
/** /**
* @param {Element} element Element to decorate. * @param {Element} element Element to decorate.
* @return {boolean} Whether the renderer can decorate the element. * @return {boolean} Whether the renderer can decorate the element.
*/ */
todomvc.view.ToDoListContainerRenderer.prototype.canDecorate = function(element) { todomvc.view.ToDoListContainerRenderer.prototype.canDecorate = function(element) {
return element.tagName == 'UL'; return element.tagName == 'UL';
}; };
/** /**
* Override this method to allow text selection in children * Override this method to allow text selection in children
* *
* @param {goog.ui.Container} container Container whose DOM is to be initialized * @param {goog.ui.Container} container Container whose DOM is to be initialized
* as it enters the document. * as it enters the document.
*/ */
todomvc.view.ToDoListContainerRenderer.prototype.initializeDom = function(container) { todomvc.view.ToDoListContainerRenderer.prototype.initializeDom = 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.dom.a11y.setRole(elem, ariaRole);
} }
}; };
\ No newline at end of file
{namespace todomvc.view} {namespace todomvc.view}
/** /**
* A todo list item template * A todo list item template
* @param content the label for this item * @param content the label for this item
*/ */
{template .toDoItem} {template .toDoItem}
<li> <li>
<div> <div>
<div class="display"> <div class="display">
<input class="check" type="checkbox" /> <input class="check" type="checkbox" />
<div class="todo-content" style="cursor: pointer;">{$content}</div> <div class="todo-content" style="cursor: pointer;">{$content}</div>
<span class="todo-destroy"></span> <span class="todo-destroy"></span>
</div> </div>
<div class="edit"> <div class="edit">
<input class="todo-input" type="text"/> <input class="todo-input" type="text"/>
</div> </div>
</div> </div>
</li> </li>
{/template} {/template}
/** /**
* A todo list item count template * A todo list item count template
* @param number the count of items * @param number the count of items
*/ */
{template .itemCount} {template .itemCount}
<span class="todo-count"> <span class="todo-count">
{call .itemCountInner data="all"/} {call .itemCountInner data="all"/}
</span> </span>
{/template} {/template}
/** /**
* A todo list item count template * A todo list item count template
* @param number the count of items * @param number the count of items
*/ */
{template .itemCountInner} {template .itemCountInner}
<span class="number">{$number}</span> <span class="word">{if $number > 1}items{else}item{/if}</span> left. <span class="number">{$number}</span> <span class="word">{if $number > 1}items{else}item{/if}</span> left.
{/template} {/template}
/** /**
* A todo list clear completed template * A todo list clear completed template
* @param number the count of items * @param number the count of items
*/ */
{template .clearCompleted} {template .clearCompleted}
<span class="todo-clear"> <span class="todo-clear">
{call .clearCompletedInner data="all"/} {call .clearCompletedInner data="all"/}
</span> </span>
{/template} {/template}
/** /**
* A todo list clear completed template * A todo list clear completed template
* @param number the count of items * @param number the count of items
*/ */
{template .clearCompletedInner} {template .clearCompletedInner}
<a href="#"> <a href="#">
Clear <span class="number-done">{$number}</span> <span class="word-done">{if $number > 1}items{else}item{/if}</span> Clear <span class="number-done">{$number}</span> <span class="word-done">{if $number > 1}items{else}item{/if}</span>
</a> </a>
{/template} {/template}
\ No newline at end of file
{ {
"id" : "todomvc", "id" : "todomvc",
"inputs" : "js/main.js", "inputs" : "js/main.js",
"paths" : "js/", "paths" : "js/",
"output-wrapper" : "(function(){%output%})();", "output-wrapper" : "(function(){%output%})();",
"mode" : "ADVANCED", "mode" : "ADVANCED",
"define" : { "define" : {
"goog.LOCALE": "en_GB" "goog.LOCALE": "en_GB"
}, },
"checks": { "checks": {
// Unfortunately, the Closure Library violates these in many places. // Unfortunately, the Closure Library violates these in many places.
// "accessControls": "ERROR", // "accessControls": "ERROR",
// "visibility": "ERROR" // "visibility": "ERROR"
"checkRegExp": "WARNING", "checkRegExp": "WARNING",
"checkTypes": "WARNING", "checkTypes": "WARNING",
"checkVars": "WARNING", "checkVars": "WARNING",
"deprecated": "WARNING", "deprecated": "WARNING",
"fileoverviewTags": "WARNING", "fileoverviewTags": "WARNING",
"invalidCasts": "WARNING", "invalidCasts": "WARNING",
"missingProperties": "WARNING", "missingProperties": "WARNING",
"nonStandardJsDocs": "WARNING", "nonStandardJsDocs": "WARNING",
"undefinedVars": "WARNING" "undefinedVars": "WARNING"
} }
} }
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