Index: chrome/common/extensions/docs/templates/articles/app_codelab3_mvc.html |
diff --git a/chrome/common/extensions/docs/templates/articles/app_codelab3_mvc.html b/chrome/common/extensions/docs/templates/articles/app_codelab3_mvc.html |
deleted file mode 100644 |
index 00212c923ddef04c1619e8df9690a1e6c12b8d90..0000000000000000000000000000000000000000 |
--- a/chrome/common/extensions/docs/templates/articles/app_codelab3_mvc.html |
+++ /dev/null |
@@ -1,428 +0,0 @@ |
-<h1 id="lab_3_model_view_controller">Create MVC</h1> |
- |
-<p>Whenever your application grows beyond a single script with a few dozen lines, |
-it gets harder and harder to manage without a good separation |
-of roles among app components. |
-One of the most common models for structuring a complex application, |
-no matter what language, |
-is the Model-View-Controller (MVC) and its variants, |
-like Model-View-Presentation (MVP).</p> |
- |
-<p>There are several frameworks to help apply |
-<a href="app_frameworks">MVC concepts</a> |
-to a Javascript application, and most of them, |
-as long as they are CSP compliant, can be used in a Chrome App. |
-In this lab, |
-we'll add an MVC model using both pure JavaScript and |
-the <a href="http://angularjs.org/">AngularJS</a> framework. |
-Most of the AngularJS code from this section was copied, |
-with small changes, from the AngularJS Todo tutorial.</p> |
- |
-<p class="note"><b>Note:</b> |
-Chrome Apps don't enforce any specific framework or programming style. |
-</p> |
- |
-<h2 id="simple">Create a simple view</h2> |
- |
-<h3 id="basic-mvc">Add MVC basics</h3> |
- |
-<p>If using AngularJS, download the |
-<a href="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js">Angular script</a> |
-and save it as |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/angularjs/simpleview/angular.min.js">angular.min.js</a>.</p> |
- |
-<p>If using JavaScript, |
-you will need to add a very simple controller with basic MVC functionalities: |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/javascript/simpleview/controller.js">JavaScript controller.js</a></p> |
- |
-<h3 id="update-view">Update view</h3> |
- |
-<p>Change the <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/angularjs/simpleview/index.html">AngularJS index.html</a> or |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/javascript/simpleview/index.html">JavaScript index.html</a> to use a simple sample: |
-</p> |
- |
-<tabs data-group="source"> |
- |
- <header tabindex="0" data-value="angular">Angular</header> |
- <header tabindex="0" data-value="js">JavaScript</header> |
- |
- <content> |
- <pre data-filename="index.html"> |
-<!doctype html> |
-<html ng-app ng-csp> |
- <head> |
- <script src="angular.min.js"></script> |
- <link rel="stylesheet" href="todo.css"> |
- </head> |
- <body> |
- <h2>Todo</h2> |
- <div> |
- <ul> |
- <li> |
- {{todoText}} |
- </li> |
- </ul> |
- <input type="text" ng-model="todoText" size="30" |
- placeholder="type your todo here"> |
- </div> |
- </body> |
-</html> |
- </pre> |
- </content> |
- <content> |
- <pre data-filename="index.html"> |
-<!doctype html> |
-<html> |
- <head> |
- <link rel="stylesheet" href="todo.css"> |
- </head> |
- <body> |
- <h2>Todo</h2> |
- <div> |
- <ul> |
- <li id="todoText"> |
- </li> |
- </ul> |
- <input type="text" id="newTodo" size="30" |
- placeholder="type your todo here"> |
- </div> |
- <script src="controller.js"></script> |
- </body> |
-</html> |
- </pre> |
- </content> |
-</tabs> |
- |
-<p class="note"><b>Note:</b> The <code>ng-csp</code> directive tells Angular to run in a "content security mode". You don't need this directive when using Angular v1.1.0+. We've included it here so that the sample works regardless of the Angular version in use.</p> |
- |
-<h3 id="stylesheet">Add stylesheet</h3> |
- |
-<p><a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/angularjs/simpleview/todo.css">AngularJS todo.css</a> and |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/javascript/simpleview/todo.css">JavaScript todo.css</a> are the same: |
-</p> |
- |
-<pre data-filename="todo.css"> |
-body { |
- font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; |
-} |
- |
-ul { |
- list-style: none; |
-} |
- |
-button, input[type=submit] { |
- background-color: #0074CC; |
- background-image: linear-gradient(top, #08C, #05C); |
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); |
- color: white; |
-} |
- |
-.done-true { |
- text-decoration: line-through; |
- color: grey; |
-} |
-</pre> |
- |
-<h3 id="check1">Check the results</h3> |
- |
-<p> |
-Check the results by reloading the app: open the app, right-click and select Reload App.</li> |
-</p> |
- |
-<h2 id="real-todo">Create real Todo list</h2> |
- |
-<p> |
-The previous sample, although interesting, is not exactly useful. |
-Let's transform it into a real Todo list, instead of a simple Todo item. |
-</p> |
- |
-<h3 id="controller">Add controller</h3> |
- |
-<p> |
-Whether using pure JavaScript or AngularJS, |
-the controller manages the Todo list: |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/angularjs/withcontroller/controller.js">AngularJS controller.js</a> or |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/javascript/withcontroller/controller.js">JavaScript controller.js</a>. |
-</p> |
- |
-<tabs data-group="source"> |
- |
- <header tabindex="0" data-value="angular">Angular</header> |
- <header tabindex="0" data-value="js">JavaScript</header> |
- |
- <content> |
- <pre data-filename="controller.js"> |
-function TodoCtrl($scope) { |
- $scope.todos = [ |
- {text:'learn angular', done:true}, |
- {text:'build an angular Chrome packaged app', done:false}]; |
- |
-$scope.addTodo = function() { |
- $scope.todos.push({text:$scope.todoText, done:false}); |
- $scope.todoText = ''; |
- }; |
- |
-$scope.remaining = function() { |
- var count = 0; |
- angular.forEach($scope.todos, function(todo) { |
- count += todo.done ? 0 : 1; |
- }); |
- return count; |
- }; |
- |
-$scope.archive = function() { |
- var oldTodos = $scope.todos; |
- $scope.todos = []; |
- angular.forEach(oldTodos, function(todo) { |
- if (!todo.done) $scope.todos.push(todo); |
- }); |
- }; |
-} |
- </pre> |
- </content> |
- <content> |
- <pre data-filename="controller.js"> |
-(function(exports) { |
- |
- var nextId = 1; |
- |
- var TodoModel = function() { |
- this.todos = {}; |
- this.listeners = []; |
- } |
- |
- TodoModel.prototype.clearTodos = function() { |
- this.todos = {}; |
- this.notifyListeners('removed'); |
- } |
- |
- TodoModel.prototype.archiveDone = function() { |
- var oldTodos = this.todos; |
- this.todos={}; |
- for (var id in oldTodos) { |
- if ( ! oldTodos[id].isDone ) { |
- this.todos[id] = oldTodos[id]; |
- } |
- } |
- this.notifyListeners('archived'); |
- } |
- |
- TodoModel.prototype.setTodoState = function(id, isDone) { |
- if ( this.todos[id].isDone != isDone ) { |
- this.todos[id].isDone = isDone; |
- this.notifyListeners('stateChanged', id); |
- } |
- } |
- |
- TodoModel.prototype.addTodo = function(text, isDone) { |
- var id = nextId++; |
- this.todos[id]={'id': id, 'text': text, 'isDone': isDone}; |
- this.notifyListeners('added', id); |
- } |
- |
- TodoModel.prototype.addListener = function(listener) { |
- this.listeners.push(listener); |
- } |
- |
- TodoModel.prototype.notifyListeners = function(change, param) { |
- var this_ = this; |
- this.listeners.forEach(function(listener) { |
- listener(this_, change, param); |
- }); |
- } |
- |
- exports.TodoModel = TodoModel; |
- |
-})(window); |
- |
- |
-window.addEventListener('DOMContentLoaded', function() { |
- |
- var model = new TodoModel(); |
- var form = document.querySelector('form'); |
- var archive = document.getElementById('archive'); |
- var list = document.getElementById('list'); |
- var todoTemplate = document.querySelector('#templates > [data-name="list"]'); |
- |
- form.addEventListener('submit', function(e) { |
- var textEl = e.target.querySelector('input[type="text"]'); |
- model.addTodo(textEl.value, false); |
- textEl.value=null; |
- e.preventDefault(); |
- }); |
- |
- archive.addEventListener('click', function(e) { |
- model.archiveDone(); |
- e.preventDefault(); |
- }); |
- |
- model.addListener(function(model, changeType, param) { |
- if ( changeType === 'removed' || changeType === 'archived') { |
- redrawUI(model); |
- } else if ( changeType === 'added' ) { |
- drawTodo(model.todos[param], list); |
- } else if ( changeType === 'stateChanged') { |
- updateTodo(model.todos[param]); |
- } |
- updateCounters(model); |
- }); |
- |
- var redrawUI = function(model) { |
- list.innerHTML=''; |
- for (var id in model.todos) { |
- drawTodo(model.todos[id], list); |
- } |
- }; |
- |
- var drawTodo = function(todoObj, container) { |
- var el = todoTemplate.cloneNode(true); |
- el.setAttribute('data-id', todoObj.id); |
- container.appendChild(el); |
- updateTodo(todoObj); |
- var checkbox = el.querySelector('input[type="checkbox"]'); |
- checkbox.addEventListener('change', function(e) { |
- model.setTodoState(todoObj.id, e.target.checked); |
- }); |
- } |
- |
- var updateTodo = function(model) { |
- var todoElement = list.querySelector('li[data-id="'+model.id+'"]'); |
- if (todoElement) { |
- var checkbox = todoElement.querySelector('input[type="checkbox"]'); |
- var desc = todoElement.querySelector('span'); |
- checkbox.checked = model.isDone; |
- desc.innerText = model.text; |
- desc.className = "done-"+model.isDone; |
- } |
- } |
- |
- var updateCounters = function(model) { |
- var count = 0; |
- var notDone = 0; |
- for (var id in model.todos) { |
- count++; |
- if ( ! model.todos[id].isDone ) { |
- notDone ++; |
- } |
- } |
- document.getElementById('remaining').innerText = notDone; |
- document.getElementById('length').innerText = count; |
- } |
- |
- updateCounters(model); |
- |
-}); |
- </pre> |
- </content> |
-</tabs> |
- |
-<h3 id="index">Update view</h3> |
- |
-<p>Change the <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/angularjs/withcontroller/index.html">AngularJS index.html</a> or |
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab3_mvc/javascript/withcontroller/index.html">JavaScript index.html</a>: |
-</p> |
- |
-<tabs data-group="source"> |
- |
- <header tabindex="0" data-value="angular">Angular</header> |
- <header tabindex="0" data-value="js">JavaScript</header> |
- |
- <content> |
- <pre data-filename="index.html"> |
-<html ng-app ng-csp> |
- <head> |
- <script src="angular.min.js"></script> |
- <script src="controller.js"></script> |
- <link rel="stylesheet" href="todo.css"> |
- </head> |
- <body> |
- <h2>Todo</h2> |
- <div ng-controller="TodoCtrl"> |
- <span>{{remaining()}} of {{todos.length}} remaining</span> |
- [ <a href="" ng-click="archive()">archive</a> ] |
- <ul> |
- <li ng-repeat="todo in todos"> |
- <input type="checkbox" ng-model="todo.done"> |
- <span class="done-{{todo.done}}">{{todo.text}}</span> |
- </li> |
- </ul> |
- <form ng-submit="addTodo()"> |
- <input type="text" ng-model="todoText" size="30" |
- placeholder="add new todo here"> |
- <input class="btn-primary" type="submit" value="add"> |
- </form> |
- </div> |
- </body> |
-</html> |
- </pre> |
- </content> |
- <content> |
- <pre data-filename="index.html"> |
-<!doctype html> |
-<html> |
- <head> |
- <link rel="stylesheet" href="todo.css"> |
- </head> |
- <body> |
- <h2>Todo</h2> |
- <div> |
- <span><span id="remaining"></span> of <span id="length"></span> remaining</span> |
- [ <a href="" id="archive">archive</a> ] |
- <ul class="unstyled" id="list"> |
- </ul> |
- <form> |
- <input type="text" size="30" |
- placeholder="add new todo here"> |
- <input class="btn-primary" type="submit" value="add"> |
- </form> |
- </div> |
- |
- <!-- poor man's template --> |
- <div id="templates" style="display: none;"> |
- <li data-name="list"> |
- <input type="checkbox"> |
- <span></span> |
- </li> |
- </div> |
- |
- <script src="controller.js"></script> |
- </body> |
-</html> |
- </pre> |
- </content> |
-</tabs> |
- |
-<p>Note how the data, stored in an array inside the controller, binds to the view and is automatically updated when it is changed by the controller.</p> |
- |
-<h3 id="check2">Check the results</h3> |
- |
-<p> |
-Check the results by reloading the app: open the app, right-click and select Reload App.</li> |
-</p> |
- |
-<h2 id="takeaways_">Takeaways</h2> |
- |
-<ul> |
-<li><p>Chrome Apps are |
-<a href="offline_apps">offline first</a>, |
-so the recommended way to include third-party scripts is to download |
-and package them inside your app.</p></li> |
-<li><p>You can use any framework you want, |
-as long as it complies with Content Security Policies |
-and other restrictions that Chrome Apps are enforced to follow.</p></li> |
-<li><p>MVC frameworks make your life easier. |
-Use them, specially if you want to build a non-trivial application.</p></li> |
-</ul> |
- |
-<h2 id="you_should_also_read">You should also read</h2> |
- |
-<ul> |
-<li><p><a href="angular_framework">Build Apps with AngularJS</a> tutorial</p></li> |
-<li><p><a href="http://angularjs.org/">AngularJS Todo</a> tutorial</p></li> |
-</ul> |
- |
-<h2 id="what_39_s_next_">What's next?</h2> |
- |
-<p>In <a href="app_codelab5_data">4 - Save and Fetch Data</a>, |
-you will modify your Todo list app so that Todo items are saved.</p> |