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

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

Issue 609433003: Updated Chrome Apps codelab from I/O 2013 Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Upload the rest of the images Created 6 years, 3 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_codelab_filesystem.html
diff --git a/chrome/common/extensions/docs/templates/articles/app_codelab_filesystem.html b/chrome/common/extensions/docs/templates/articles/app_codelab_filesystem.html
new file mode 100644
index 0000000000000000000000000000000000000000..d82037ab2b94e77a4fb13002c17af0da6484a70a
--- /dev/null
+++ b/chrome/common/extensions/docs/templates/articles/app_codelab_filesystem.html
@@ -0,0 +1,270 @@
+<h1 id="export-to-filesystem">
+ <span class="h1-step">Step 6:</span>
+ Export Todos to the Filesystem
+</h1>
+
+<p class="note">
+ <strong>Want to start fresh from here?</strong>
+ Find the previous step's code in the <a href="https://github.com/mangini/io13-codelab/archive/master.zip">reference code zip</a> under <strong><em>cheat_code > solution_for_step5</strong></em>.
+</p>
+
+<p>In this step, you will learn:</p>
+
+<ul>
+ <li>How to get a reference to a file in the external filesystem.</li>
+ <li>How to write to the filesystem.</li>
+</ul>
+
+<p>
+ <em>Estimated time to complete this step: 20 minutes.</em>
+ <br>
+ To preview what you will complete in this step, <a href="#launch">jump down to the bottom of this page &#8595;</a>.
+</p>
+
+<h2 id="export-todos">Export todos</h2>
+
+<p>In this step, we will add an export button to the app. When clicked, the current
+todo items will be saved to a text file selected by the user. If the file
+exists, it will be replaced. Otherwise, a new file will be created.</p>
+
+<h3 id="update-permissions">Update permissions</h3>
+
+<p>File system permissions can be requested as a string for read-only access, or an Object with additional properties. For example:</p>
+
+<pre>
+// Read only
+"permissions": [<b>"fileSystem"</b>]
+
+// Read and write
+"permissions": [<b>{"fileSystem": ["write"]}</b>]
+
+// Read, write, autocomplate previous input, and select folder directories instead of files
+"permissions": [<b>{"fileSystem": ["write", "retainEntries", "directory"]}</b>]
+</pre>
+
+<p>For our purposes, we need read and write access. In <strong><em>manifest.json</em></strong>, request the <code>{fileSystem: [ "write" ] }</code> permission:</p>
+
+<pre data-filename="manifest.json">
+"permissions": ["storage", "alarms", "notifications", "webview",
+ "&lt;all_urls&gt;"<b>, { "fileSystem": ["write"] }</b> ],
+</pre>
+
+
+<h3 id="update-html-view">Update HTML view</h3>
+
+<p>In <strong><em>index.html</em></strong>, add an <b>Export to disk</b> button and
+a <code>div</code> where we will show a status message:</p>
+
+<pre data-filename="index.html">
+&lt;footer id="info"&gt;
+ &lt;button id="toggleAlarm"&gt;Activate alarm&lt;/button&gt;
+ <b>&lt;button id="exportToDisk"&gt;Export to disk&lt;/button&gt;</b>
+ <b>&lt;div id="status"&gt;&lt;/div&gt;</b>
+ ...
+&lt;/footer&gt;
+</pre>
+
+<p>Also in <em>index.html</em>, load the <em>export.js</em> script we will create next:</p>
+
+<pre data-filename="index.html">
+...
+&lt;script src="js/alarms.js"&gt;&lt;/script&gt;
+<b>&lt;script src="js/export.js"&gt;&lt;/script&gt;</b>
+</pre>
+
+<h3 id="create-js">Create export script</h3>
+
+<p>Create a new JavaScript file named <strong><em>export.js</em></strong> using the code below. Save it in the <strong><em>js</em></strong>
+ folder.</p>
+
+<pre data-filename="export.js">
+(function() {
+
+ var dbName = 'todos-vanillajs';
+
+ var savedFileEntry, fileDisplayPath;
+
+ function getTodosAsText(callback) {
+ }
+
+ function exportToFileEntry(fileEntry) {
+ }
+
+ function doExportToDisk() {
+ }
+
+ document.getElementById('exportToDisk').addEventListener('click', doExportToDisk);
+
+})();
+</pre>
+
+<p>Right now, <em>export.js</em> only contains a click listener on the <strong>Export to disk</strong> button and stubs for <code>getTodosAsText()</code>, <code>exportToFileEntry</code>, and <code>doExportToDisk()</code>.</p>
+
+<h3 id="get-todos-as-text">Get todo items as text</h3>
+
+<p>Update <code>getTodosAsText()</code> so that it reads todos from <code>chrome.storage.local</code> and generates a textual representation of them:</p>
+
+<pre data-filename="export.js">
+function getTodosAsText(callback) {
+<b> chrome.storage.local.get(dbName, function(storedData) {
+ var text = '';
+
+ if ( storedData[dbName].todos ) {
+ storedData[dbName].todos.forEach(function(todo) {
+ text += '- ';
+ if ( todo.completed ) {
+ text += '[DONE] ';
+ }
+ text += todo.title;
+ text += '\n';
+ }, '');
+ }
+
+ callback(text);
+
+ }.bind(this));</b>
+}
+</pre>
+
+<h3 id="choose-file">Choose a file</h3>
+
+<p>Update <code>doExportToDisk()</code> with <code><a href="/apps/fileSystem#method-chooseEntry">chrome.fileSystem.chooseEntry()</a></code> to allow the user to choose a file:</p>
+
+<pre data-filename="export.js">
+function doExportToDisk() {
+
+<b> if (savedFileEntry) {
+
+ exportToFileEntry(savedFileEntry);
+
+ } else {
+
+ chrome.fileSystem.chooseEntry( {
+ type: 'saveFile',
+ suggestedName: 'todos.txt',
+ accepts: [ { description: 'Text files (*.txt)',
+ extensions: ['txt']} ],
+ acceptsAllTypes: true
+ }, exportToFileEntry);
+
+ }</b>
+}
+</pre>
+
+<p>The first parameter of <code>chrome.fileSystem.chooseEntry()</code> is an object of options. The second parameter is a callback method.</p>
+
+<p>If we already have a saved <code>FileEntry</code>, we'll use that instead when we call <code>exportToFileEntry()</code>.
+File references will exist for the lifetime of the object representing the <code>FileEntry</code>.
+In our example, we tied <code>FileEntry</code> to the app window so the JavaScript code can write to the
+selected file without any user interaction as long as the app window remains open.</p>
+
+<h3 id="use-fileentry">Use FileEntry to write todos items to disk</h3>
+
+<p>Update <code>exportToFileEntry()</code> to save the todos as text via the <code>FileEntry</code> Web API:</p>
+
+<pre data-filename="export.js">
+function exportToFileEntry(fileEntry) {
+<b> savedFileEntry = fileEntry;
+
+ var status = document.getElementById('status');
+
+ // Use this to get a file path appropriate for displaying
+ chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
+ fileDisplayPath = path;
+ status.innerText = 'Exporting to '+path;
+ });
+
+ getTodosAsText( function(contents) {
+
+ fileEntry.createWriter(function(fileWriter) {
+
+ var truncated = false;
+ var blob = new Blob([contents]);
+
+ fileWriter.onwriteend = function(e) {
+ if (!truncated) {
+ truncated = true;
+ // You need to explicitly set the file size to truncate
+ // any content that might have been there before
+ this.truncate(blob.size);
+ return;
+ }
+ status.innerText = 'Export to '+fileDisplayPath+' completed';
+ };
+
+ fileWriter.onerror = function(e) {
+ status.innerText = 'Export failed: '+e.toString();
+ };
+
+ fileWriter.write(blob);
+
+ });
+ });</b>
+}
+</pre>
+
+<p><code><a href="/apps/fileSystem#method-getDisplayPath">chrome.fileSystem.getDisplayPath()</a></code> is used to get a displayable file path that we'll output to the status <code>div</code>.</p>
+
+<p>Use <code>fileEntry.createWriter()</code> to create a <code>FileWriter</code> object. <code>fileWriter.write()</code> can then write a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a> to the filesystem. Use <code>fileWriter.onwriteend()</code> and <code>fileWriter.onerror()</code> to update the status <code>div</code>.</p>
+
+<!-- <code>fileWriter.truncate()</code> -->
+
+<p>For more information about <code>FileEntry</code>, read <a href="http://www.html5rocks.com/en/tutorials/file/filesystem/"><em>Exploring the FileSystem APIs</em></a> on HTML5Rocks, or refer to the <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/FileEntry">FileEntry docs</a></code> on MDN.</p>
+
+<h3 id="persistance">Persist FileEntry objects</h3>
+
+<p><strong>Advanced</strong>: <code>FileEntry</code> objects cannot be persisted indefinitely. This means
+that your app will need to ask the user to choose a file every time the app is
+launched. However, <a href="/apps/fileSystem#method-restoreEntry">restoreEntry()</a> is an
+option to
+restore a <code>FileEntry</code> if your app was forced to restart due to a runtime crash or update.</p>
+
+<p>If you wish, experiment by saving the ID returned by
+<a href="/apps/fileSystem.html#method-retainEntry">retainEntry()</a>
+and restoring it on app restart. (Hint: Add a listener to the <code>onRestarted</code> event
+in the background page.)</p>
+
+<h2 id="launch">Launch your finished Todo app</h2>
+
+<p>You are done Step 6! Reload your app and add some todos. Click <b>Export to disk</b> to export your todos to a .txt file.</p>
+
+<figure>
+ <img src="{{static}}/images/app_codelab/step6-completed.png" alt="The Todo app with exported todos"/>
+</figure>
+
+<h2 id="recap">Recap APIs referenced in this step</h2>
+
+<p>For more detailed information about some of the APIs introduced in this step, refer to:</p>
+
+<ul>
+ <li>
+ <a href="/apps/app_storage#filesystem" title="Read 'Using the Chrome Filesystem API' in the Chrome developer docs">Using the Chrome Filesystem API</a>
+ <a href="#export-todos" class="anchor-link-icon" title="This feature mentioned in 'Export todos'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/declare_permissions" title="Read 'Declare Permissions' in the Chrome developer docs">Declare Permissions</a>
+ <a href="#update-permissions" class="anchor-link-icon" title="This feature mentioned in 'Update permissions'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/storage#method-StorageArea-get" title="Read 'chrome.storage.local.get()' in the Chrome developer docs">chrome.storage.local.get()</a>
+ <a href="#get-todos-as-text" class="anchor-link-icon" title="This feature mentioned in 'Get todo items as text'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/fileSystem#method-chooseEntry" title="Read 'chrome.fileSystem.chooseEntry()' in the Chrome developer docs">chrome.fileSystem.chooseEntry()</a>
+ <a href="#choose-file" class="anchor-link-icon" title="This feature mentioned in 'Choose a file'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/fileSystem#method-getDisplayPath" title="Read 'chrome.fileSystem.getDisplayPath()' in the Chrome developer docs">chrome.fileSystem.getDisplayPath()</a>
+ <a href="#use-fileentry" class="anchor-link-icon" title="This feature mentioned in 'Use FileEntry to write todos items to disk'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/fileSystem#method-restoreEntry" title="Read 'chrome.fileSystem.restoreEntry()' in the Chrome developer docs">chrome.fileSystem.restoreEntry()</a>
+ <a href="#persistance" class="anchor-link-icon" title="This feature mentioned in 'Persist FileEntry objects'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/fileSystem#method-retainEntry" title="Read 'chrome.fileSystem.retainEntry()' in the Chrome developer docs">chrome.fileSystem.retainEntry()</a>
+ <a href="#persistance" class="anchor-link-icon" title="This feature mentioned in 'Persist FileEntry objects'">&#8593;</a>
+ </li>
+</ul>
+
+<p>Ready to continue onto the next step? Go to <a href="app_codelab_publish.html">Step 7 - Publish your app &raquo;</a></p>

Powered by Google App Engine
This is Rietveld 408576698