Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9690)

Unified Diff: chrome/common/extensions/docs/templates/articles/app_codelab5_data.html

Issue 645693006: Updated Chrome Apps codelab (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/templates/articles/app_codelab5_data.html
diff --git a/chrome/common/extensions/docs/templates/articles/app_codelab5_data.html b/chrome/common/extensions/docs/templates/articles/app_codelab5_data.html
index 684f6b1a2307c98126298823af0110438c94dc07..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/chrome/common/extensions/docs/templates/articles/app_codelab5_data.html
+++ b/chrome/common/extensions/docs/templates/articles/app_codelab5_data.html
@@ -1,432 +0,0 @@
-<h1 id="lab_5_manage_data">Save and Fetch Data</h1>
-
-<p>The <a href="app_codelab3_mvc">sample from Lab 3</a>
-uses a static array of Todos.
-Every time your app restarts,
-whatever you&#39;ve changed is lost.
-In this section, we will save every change using
-<a href="storage">chrome.storage.sync</a>.
-</p>
-
-<p>
-This lets you store <em>small things</em> that automatically sync to the cloud
-if you are online and logged in to Chrome.
-If you are offline or unlogged, it saves locally and transparently:
-you don&#39;t have to handle online check and offline fallback in your application.
-</p>
-
-<h2 id="save_your_todos_in_the_cloud">Save your Todos in the cloud</h2>
-
-<p class="note"><b>Note:</b>
-Chrome Sync Storage is not intended to be used as a generic database.
-There are several restrictions on the amount of information you can save,
-so it is more appropriate to save settings and other small chunks of data. </p>
-
-<h3 id="manifest">Update manifest</h3>
-
-<p>Request permission to use storage in your manifest.
-Permissions are the same in the
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/1_storage_sync/manifest.json">AngularJS manifest.json</a> and
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/javascript/1_storage_sync/manifest.json">JavaScript manifest.json</a>:
-</p>
-
-<pre data-filename="manifest.json">
-{
- ... ,
- &quot;permissions&quot;: [&quot;storage&quot;]
-}
-</pre>
-
-<h3 id="simple-controller">Update controller</h3>
-
-<p>Change your controller to get the Todo list
-from syncable storage instead of a static list:
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/1_storage_sync/controller.js">AngularJS controller.js</a> or
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/javascript/1_storage_sync/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">
-// Notice that chrome.storage.sync.get is asynchronous
-chrome.storage.sync.get(&#39;todolist&#39;, function(value) {
- // The $apply is only necessary to execute the function inside Angular scope
- $scope.$apply(function() {
- $scope.load(value);
- });
-});
-
-// If there is saved data in storage, use it. Otherwise, bootstrap with sample todos
-$scope.load = function(value) {
- if (value &amp;&amp; value.todolist) {
- $scope.todos = value.todolist;
- } else {
- $scope.todos = [
- {text:&#39;learn angular&#39;, done:true},
- {text:&#39;build an angular app&#39;, done:false}];
- }
-}
-
-$scope.save = function() {
- chrome.storage.sync.set({&#39;todolist&#39;: $scope.todos});
-};
- </pre>
- </content>
- <content>
- <pre data-filename="controller.js">
- /**
- * Listen to changes in the model and trigger the appropriate changes in the view
- **/
- model.addListener(function(model, changeType, param) {
- if ( changeType === 'removed' || changeType === 'archived' || changeType === 'reset') {
- redrawUI(model);
- } else if ( changeType === 'added' ) {
- drawTodo(model.todos[param], list);
- } else if ( changeType === 'stateChanged') {
- updateTodo(model.todos[param]);
- }
- storageSave();
- updateCounters(model);
- });
-
-// If there is saved data in storage, use it. Otherwise, bootstrap with sample todos
- var storageLoad = function() {
- chrome.storage.sync.get('todolist', function(value) {
- if (value && value.todolist) {
- model.setTodos(value.todolist);
- } else {
- model.addTodo('learn Chrome Apps', true);
- model.addTodo('build a Chrome App', false);
- }
- });
- }
-
- var storageSave = function() {
- chrome.storage.sync.set({'todolist': model.todos});
- };
- </pre>
- </content>
-</tabs>
-
-<h3 id="simple-view">Update view</h3>
-
-<p>In the view,
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/1_storage_sync/index.html">AngularJs index.hmtl</a> or
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/javascript/1_storage_sync/index.html">JavaScript index.html</a>,
-save the data whenever it changes.
-In AngularJS,
-we call <code>save()</code> explicitedly
-but there are many ways of doing this.
-For example,
-you could also use <code>$watchers</code> on the scope.
-</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">
-...
- [ &lt;a href=&quot;&quot; ng-click=&quot;archive() || save()&quot;&gt;archive&lt;/a&gt; ]
-...
- &lt;input type=&quot;checkbox&quot; ng-model=&quot;todo.done&quot; ng-change=&quot;save()&quot;&gt;
-...
- &lt;form ng-submit=&quot;addTodo() || save()&quot;&gt;
-...
- </pre>
- </content>
- <content>
- <pre data-filename="index.html">
-&lt;form&gt;
- &lt;input type="text" size="30"
- placeholder="add new todo here"&gt;
- &lt;input class="btn-primary" type="submit" value="add"&gt;
-&lt;/form&gt;
- </pre>
- </content>
-
-</tabs>
-
-<h3 id="results1">Check the results</h3>
-
-<p>Check the results by reloading the app:
-open the app, right-click and select Reload App.
-You can now add Todo items, close the app,
-and the new items will still be there when you reopen the app.
-</p>
-
-<p>
-If you get stuck and want to see the app in action,
-go to <code>chrome://extensions</code>,
-load the unpacked app, and launch the app from a new tab:
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab5_data/angularjs/1_storage_sync">Angular JS 1_storage_sync</a> or
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab5_data/javascript/1_storage_sync">JavaScript 1_storage_sync</a>.
-</p>
-
-<h2 id="handle_drag_and_dropped_files_and_urls">Handle drag-and-dropped files and URLs</h2>
-
-<p>Suppose you want to create Todos associated with local files and/or URLs.
-The natural way of doing this is to accept dropped items.
-It&#39;s simple enough to add drag-and-drop support
-in a Chrome App using the standard
-<a href="http://www.html5rocks.com/en/tutorials/dnd/basics/">HTML5 Drag-and-Drop API</a>.
-</p>
-
-<h3 id="dd-controller">Update controller</h3>
-
-<p>In the controller,
-add code to handle the events of dragover, dragleave, and drop:
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/2_drop_files/controller.js">AngularJS controller.js</a> or
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/javascript/2_drop_files/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">
-var defaultDropText = &quot;Or drop files here...&quot;;
-$scope.dropText = defaultDropText;
-
-// on dragOver, we will change the style and text accordingly, depending on
-// the data being transferred
-var dragOver = function(e) {
- e.stopPropagation();
- e.preventDefault();
- var valid = e.dataTransfer &amp;&amp; e.dataTransfer.types
- &amp;&amp; ( e.dataTransfer.types.indexOf(&#39;Files&#39;) &gt;= 0
- || e.dataTransfer.types.indexOf(&#39;text/uri-list&#39;) &gt;=0 )
- $scope.$apply(function() {
- $scope.dropText = valid ? &quot;Drop files and remote images and they will become Todos&quot;
- : &quot;Can only drop files and remote images here&quot;;
- $scope.dropClass = valid ? &quot;dragging&quot; : &quot;invalid-dragging&quot;;
- });
-}
-
-// reset style and text to the default
-var dragLeave = function(e) {
- $scope.$apply(function() {
- $scope.dropText = defaultDropText;
- $scope.dropClass = &#39;&#39;;
- });
-}
-
-// on drop, we create the appropriate TODOs using dropped data
-var drop = function(e) {
- e.preventDefault();
- e.stopPropagation();
-
-var newTodos=[];
- if (e.dataTransfer.types.indexOf(&#39;Files&#39;) &gt;= 0) {
- var files = e.dataTransfer.files;
- for (var i = 0; i &lt; files.length; i++) {
- var text = files[i].name+&#39;, &#39;+files[i].size+&#39; bytes&#39;;
- newTodos.push({text:text, done:false, file: files[i]});
- }
- } else { // uris
- var uri=e.dataTransfer.getData(&quot;text/uri-list&quot;);
- newTodos.push({text:uri, done:false, uri: uri});
- }
-
-$scope.$apply(function() {
- $scope.dropText = defaultDropText;
- $scope.dropClass = &#39;&#39;;
- for (var i = 0; i &lt; newTodos.length; i++) {
- $scope.todos.push(newTodos[i]);
- }
- $scope.save();
- });
-}
-
-document.body.addEventListener(&quot;dragover&quot;, dragOver, false);
-document.body.addEventListener(&quot;dragleave&quot;, dragLeave, false);
-document.body.addEventListener(&quot;drop&quot;, drop, false);
- </pre>
- </content>
- <content>
- <pre data-filename="controller.js">
-var defaultDropText = "Or drop files here...";
-
-var dropText = document.getElementById('dropText');
-dropText.innerText = defaultDropText;
-
-// on dragOver, we will change the style and text accordingly, depending on
-// the data being transfered
-var dragOver = function(e) {
- e.stopPropagation();
- e.preventDefault();
- var valid = isValid(e.dataTransfer);
- if (valid) {
- dropText.innerText="Drop files and remote images and they will become Todos";
- document.body.classList.add("dragging");
- } else {
- dropText.innerText="Can only drop files and remote images here";
- document.body.classList.add("invalid-dragging");
- }
-}
-
-var isValid = function(dataTransfer) {
- return dataTransfer && dataTransfer.types
- && ( dataTransfer.types.indexOf('Files') >= 0
- || dataTransfer.types.indexOf('text/uri-list') >=0 )
-}
-
-// reset style and text to the default
-var dragLeave = function(e) {
- dropText.innerText=defaultDropText;
- document.body.classList.remove('dragging');
- document.body.classList.remove('invalid-dragging');
-}
-
-// on drop, we create the appropriate TODOs using dropped data
-var drop = function(e, model) {
- e.preventDefault();
- e.stopPropagation();
- if (isValid(e.dataTransfer)) {
- if (e.dataTransfer.types.indexOf('Files') >= 0) {
- var files = e.dataTransfer.files;
- for (var i = 0; i &lt; files.length; i++) {
- var text = files[i].name+', '+files[i].size+' bytes';
- model.addTodo(text, false, {file: files[i]});
- }
- } else { // uris
- var uri=e.dataTransfer.getData("text/uri-list");
- model.addTodo(uri, false, {uri: uri});
- }
- }
-
- dragLeave();
-}
-
-exports.setDragHandlers = function(model) {
- document.body.addEventListener("dragover", dragOver, false);
- document.body.addEventListener("dragleave", dragLeave, false);
- document.body.addEventListener("drop", function(e) {
- drop(e, model);
- }, false);
-}
- </pre>
- </content>
-
-</tabs>
-
-<h3 id="dd-view">Update view</h3>
-
-<p>If using AngularJS,
-let&#39;s move the Angular scope definition from the div to the body in the
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/2_drop_files/index.html">AngularJS index.html</a> file to make all the area of the window accept the drop event and still work on the same scope.
-Also, let&#39;s associate the body&#39;s CSS class with the Angular controller&#39;s class,
-so we can change the class directly in the scope and have it automatically changed in the DOM:
-</p>
-
-<tabs data-group="source">
-
- <header tabindex="0" data-value="angular">Angular</header>
-
- <content>
- <pre data-filename="index.html">
-&lt;body ng-controller=&quot;TodoCtrl&quot; ng-class=&quot;dropClass&quot;&gt;
-&lt;!-- remember to remove the ng-controller attribute from the div where it was before --&gt;
- </pre>
- </content>
-
-</tabs>
-
-<p>Add a message placeholder
-(in <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/2_drop_files/index.html">AngularJS index.html</a> or
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/javascript/2_drop_files/index.html">JavaScript index.html</a>) to warn the user that some types of dragging are not allowed:
-</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">
-&lt;div&gt;
- &#123;&#123;dropText&#125;&#125;
-&lt;/div&gt;
- </pre>
- </content>
- <content>
- <pre data-filename="index.html">
-&lt;div id=&quot;dropText&quot;&gt;
-&lt;/div&gt;
- </pre>
- </content>
-
-</tabs>
-
-<h3 id="dd-css">Update stylesheet</h3>
-
-<p>Add appropriate styling for the <code>dragging</code> and
-<code>invalid-dragging</code> CSS classes in the css.
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/angularjs/2_drop_files/todo.css">AngularJS todo.css</a> and
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab5_data/javascript/2_drop_files/todo.css">JavaScript todo.css</a> are the same.
-Here we used a green or red background color animation:
-</p>
-
-<pre data-filename="todo.css">
-@-webkit-keyframes switch-green {
- from { background-color: white;} to {background-color: rgb(163, 255, 163);}
-}
-@-webkit-keyframes switch-red {
- from { background-color: white;} to {background-color: rgb(255, 203, 203);}
-}
-.dragging {
- -webkit-animation: switch-green 0.5s ease-in-out 0 infinite alternate;
-}
-
-.invalid-dragging {
- -webkit-animation: switch-red 0.5s ease-in-out 0 infinite alternate;
-}
-</pre>
-
-<h3 id="results2">Check the results</h3>
-
-<p>Check the results by reloading the app:
-open the app, right-click and select Reload App.
-You can now drag files into the Todo list.</p>
-
-<p>
-If you get stuck and want to see the app in action,
-go to <code>chrome://extensions</code>, load the unpacked app,
-and launch the app from a new tab:
-<a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab5_data/angularjs/2_drop_files">AngularJS 2_drop_files</a>
-or <a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab5_data/javascript/2_drop_files">JavaScript 2_drop_files</a>.
-</p>
-
-<h2 id="challenge_">Challenge</h2>
-
-<p>The current code only saves the file reference, but it doesn&#39;t open the file. Using the <a href="http://www.html5rocks.com/en/tutorials/file/filesystem/">HTML5 Filesystem API</a>, save the file contents in a sandboxed filesystem. When the Todo item is archived, remove the corresponding file from the sandboxed filesystem. Add an &quot;open&quot; link on each Todo that has an associated file. When the item is clicked and the file exists in the sandboxed filesystem, use the Chrome App <a href="fileSystem">Filesystem API</a> to request a writable FileEntry from the user. Save the file data from the sandboxed filesystem into that entry.</p>
-
-<p class="note"><b>Tip:</b> managing file entries using the raw HTML5 Filesystem API is not trivial. You might want to use a wrapper library, like Eric Bidelman&#39;s <a href="https://github.com/ebidel/filer.js">filer.js</a>.</p>
-
-<h2 id="takeaways_">Takeaways</h2>
-
-<ul>
-<li><p>Use <a href="storage">chrome.storage.sync</a> to save small data that you need to be sync&#39;ed among devices, like configuration options, application state, etc. The sync is automatic, as long as the same user is logged into Chrome on all devices.</p></li>
-<li><p>Chrome Apps support almost all HTML5 APIs, such as drag and drop.
-HTML Filesystem API is also supported, with extra features from the Chrome App&#39;s
-<a href="fileSystem">Filesystem API</a>,
-like asking the user to pick files on her local disk for read and write.
-The vanilla HTML5 Filesystem API only allows access to a sandboxed filesystem.</p></li>
-</ul>
-
-<h2 id="you_should_also_read">You should also read</h2>
-
-<p><a href="app_storage">Manage Data</a> tutorial</p>
-
-<h2 id="what_39_s_next_">What's next?</h2>
-
-<p>In <a href="app_codelab6_lifecycle">5 - Manage App Lifecycle</a>,
-you will learn the basics of the Chrome App lifecycle. </p>

Powered by Google App Engine
This is Rietveld 408576698