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

Side by Side 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, 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 unified diff | Download patch
OLDNEW
(Empty)
1 <h1 id="export-to-filesystem">
2 <span class="h1-step">Step 6:</span>
3 Export Todos to the Filesystem
4 </h1>
5
6 <p class="note">
7 <strong>Want to start fresh from here?</strong>
8 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>.
9 </p>
10
11 <p>In this step, you will learn:</p>
12
13 <ul>
14 <li>How to get a reference to a file in the external filesystem.</li>
15 <li>How to write to the filesystem.</li>
16 </ul>
17
18 <p>
19 <em>Estimated time to complete this step: 20 minutes.</em>
20 <br>
21 To preview what you will complete in this step, <a href="#launch">jump down to the bottom of this page &#8595;</a>.
22 </p>
23
24 <h2 id="export-todos">Export todos</h2>
25
26 <p>In this step, we will add an export button to the app. When clicked, the curr ent
27 todo items will be saved to a text file selected by the user. If the file
28 exists, it will be replaced. Otherwise, a new file will be created.</p>
29
30 <h3 id="update-permissions">Update permissions</h3>
31
32 <p>File system permissions can be requested as a string for read-only access, or an Object with additional properties. For example:</p>
33
34 <pre>
35 // Read only
36 "permissions": [<b>"fileSystem"</b>]
37
38 // Read and write
39 "permissions": [<b>{"fileSystem": ["write"]}</b>]
40
41 // Read, write, autocomplate previous input, and select folder directories inste ad of files
42 "permissions": [<b>{"fileSystem": ["write", "retainEntries", "directory"]}</b>]
43 </pre>
44
45 <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>
46
47 <pre data-filename="manifest.json">
48 "permissions": ["storage", "alarms", "notifications", "webview",
49 "&lt;all_urls&gt;"<b>, { "fileSystem": ["write"] }</b> ],
50 </pre>
51
52
53 <h3 id="update-html-view">Update HTML view</h3>
54
55 <p>In <strong><em>index.html</em></strong>, add an <b>Export to disk</b> button and
56 a <code>div</code> where we will show a status message:</p>
57
58 <pre data-filename="index.html">
59 &lt;footer id="info"&gt;
60 &lt;button id="toggleAlarm"&gt;Activate alarm&lt;/button&gt;
61 <b>&lt;button id="exportToDisk"&gt;Export to disk&lt;/button&gt;</b>
62 <b>&lt;div id="status"&gt;&lt;/div&gt;</b>
63 ...
64 &lt;/footer&gt;
65 </pre>
66
67 <p>Also in <em>index.html</em>, load the <em>export.js</em> script we will creat e next:</p>
68
69 <pre data-filename="index.html">
70 ...
71 &lt;script src="js/alarms.js"&gt;&lt;/script&gt;
72 <b>&lt;script src="js/export.js"&gt;&lt;/script&gt;</b>
73 </pre>
74
75 <h3 id="create-js">Create export script</h3>
76
77 <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>
78 folder.</p>
79
80 <pre data-filename="export.js">
81 (function() {
82
83 var dbName = 'todos-vanillajs';
84
85 var savedFileEntry, fileDisplayPath;
86
87 function getTodosAsText(callback) {
88 }
89
90 function exportToFileEntry(fileEntry) {
91 }
92
93 function doExportToDisk() {
94 }
95
96 document.getElementById('exportToDisk').addEventListener('click', doExportToDi sk);
97
98 })();
99 </pre>
100
101 <p>Right now, <em>export.js</em> only contains a click listener on the <strong>E xport to disk</strong> button and stubs for <code>getTodosAsText()</code>, <code >exportToFileEntry</code>, and <code>doExportToDisk()</code>.</p>
102
103 <h3 id="get-todos-as-text">Get todo items as text</h3>
104
105 <p>Update <code>getTodosAsText()</code> so that it reads todos from <code>chrome .storage.local</code> and generates a textual representation of them:</p>
106
107 <pre data-filename="export.js">
108 function getTodosAsText(callback) {
109 <b> chrome.storage.local.get(dbName, function(storedData) {
110 var text = '';
111
112 if ( storedData[dbName].todos ) {
113 storedData[dbName].todos.forEach(function(todo) {
114 text += '- ';
115 if ( todo.completed ) {
116 text += '[DONE] ';
117 }
118 text += todo.title;
119 text += '\n';
120 }, '');
121 }
122
123 callback(text);
124
125 }.bind(this));</b>
126 }
127 </pre>
128
129 <h3 id="choose-file">Choose a file</h3>
130
131 <p>Update <code>doExportToDisk()</code> with <code><a href="/apps/fileSystem#met hod-chooseEntry">chrome.fileSystem.chooseEntry()</a></code> to allow the user to choose a file:</p>
132
133 <pre data-filename="export.js">
134 function doExportToDisk() {
135
136 <b> if (savedFileEntry) {
137
138 exportToFileEntry(savedFileEntry);
139
140 } else {
141
142 chrome.fileSystem.chooseEntry( {
143 type: 'saveFile',
144 suggestedName: 'todos.txt',
145 accepts: [ { description: 'Text files (*.txt)',
146 extensions: ['txt']} ],
147 acceptsAllTypes: true
148 }, exportToFileEntry);
149
150 }</b>
151 }
152 </pre>
153
154 <p>The first parameter of <code>chrome.fileSystem.chooseEntry()</code> is an obj ect of options. The second parameter is a callback method.</p>
155
156 <p>If we already have a saved <code>FileEntry</code>, we'll use that instead whe n we call <code>exportToFileEntry()</code>.
157 File references will exist for the lifetime of the object representing the <code >FileEntry</code>.
158 In our example, we tied <code>FileEntry</code> to the app window so the JavaScri pt code can write to the
159 selected file without any user interaction as long as the app window remains ope n.</p>
160
161 <h3 id="use-fileentry">Use FileEntry to write todos items to disk</h3>
162
163 <p>Update <code>exportToFileEntry()</code> to save the todos as text via the <co de>FileEntry</code> Web API:</p>
164
165 <pre data-filename="export.js">
166 function exportToFileEntry(fileEntry) {
167 <b> savedFileEntry = fileEntry;
168
169 var status = document.getElementById('status');
170
171 // Use this to get a file path appropriate for displaying
172 chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
173 fileDisplayPath = path;
174 status.innerText = 'Exporting to '+path;
175 });
176
177 getTodosAsText( function(contents) {
178
179 fileEntry.createWriter(function(fileWriter) {
180
181 var truncated = false;
182 var blob = new Blob([contents]);
183
184 fileWriter.onwriteend = function(e) {
185 if (!truncated) {
186 truncated = true;
187 // You need to explicitly set the file size to truncate
188 // any content that might have been there before
189 this.truncate(blob.size);
190 return;
191 }
192 status.innerText = 'Export to '+fileDisplayPath+' completed';
193 };
194
195 fileWriter.onerror = function(e) {
196 status.innerText = 'Export failed: '+e.toString();
197 };
198
199 fileWriter.write(blob);
200
201 });
202 });</b>
203 }
204 </pre>
205
206 <p><code><a href="/apps/fileSystem#method-getDisplayPath">chrome.fileSystem.getD isplayPath()</a></code> is used to get a displayable file path that we'll output to the status <code>div</code>.</p>
207
208 <p>Use <code>fileEntry.createWriter()</code> to create a <code>FileWriter</code> object. <code>fileWriter.write()</code> can then write a <a href="https://devel oper.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 t he status <code>div</code>.</p>
209
210 <!-- <code>fileWriter.truncate()</code> -->
211
212 <p>For more information about <code>FileEntry</code>, read <a href="http://www.h tml5rocks.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>
213
214 <h3 id="persistance">Persist FileEntry objects</h3>
215
216 <p><strong>Advanced</strong>: <code>FileEntry</code> objects cannot be persisted indefinitely. This means
217 that your app will need to ask the user to choose a file every time the app is
218 launched. However, <a href="/apps/fileSystem#method-restoreEntry">restoreEntry() </a> is an
219 option to
220 restore a <code>FileEntry</code> if your app was forced to restart due to a runt ime crash or update.</p>
221
222 <p>If you wish, experiment by saving the ID returned by
223 <a href="/apps/fileSystem.html#method-retainEntry">retainEntry()</a>
224 and restoring it on app restart. (Hint: Add a listener to the <code>onRestarted< /code> event
225 in the background page.)</p>
226
227 <h2 id="launch">Launch your finished Todo app</h2>
228
229 <p>You are done Step 6! Reload your app and add some todos. Click <b>Export to d isk</b> to export your todos to a .txt file.</p>
230
231 <figure>
232 <img src="{{static}}/images/app_codelab/step6-completed.png" alt="The Todo app with exported todos"/>
233 </figure>
234
235 <h2 id="recap">Recap APIs referenced in this step</h2>
236
237 <p>For more detailed information about some of the APIs introduced in this step, refer to:</p>
238
239 <ul>
240 <li>
241 <a href="/apps/app_storage#filesystem" title="Read 'Using the Chrome Filesys tem API' in the Chrome developer docs">Using the Chrome Filesystem API</a>
242 <a href="#export-todos" class="anchor-link-icon" title="This feature mention ed in 'Export todos'">&#8593;</a>
243 </li>
244 <li>
245 <a href="/apps/declare_permissions" title="Read 'Declare Permissions' in the Chrome developer docs">Declare Permissions</a>
246 <a href="#update-permissions" class="anchor-link-icon" title="This feature m entioned in 'Update permissions'">&#8593;</a>
247 </li>
248 <li>
249 <a href="/apps/storage#method-StorageArea-get" title="Read 'chrome.storage.l ocal.get()' in the Chrome developer docs">chrome.storage.local.get()</a>
250 <a href="#get-todos-as-text" class="anchor-link-icon" title="This feature me ntioned in 'Get todo items as text'">&#8593;</a>
251 </li>
252 <li>
253 <a href="/apps/fileSystem#method-chooseEntry" title="Read 'chrome.fileSystem .chooseEntry()' in the Chrome developer docs">chrome.fileSystem.chooseEntry()</a >
254 <a href="#choose-file" class="anchor-link-icon" title="This feature mentione d in 'Choose a file'">&#8593;</a>
255 </li>
256 <li>
257 <a href="/apps/fileSystem#method-getDisplayPath" title="Read 'chrome.fileSys tem.getDisplayPath()' in the Chrome developer docs">chrome.fileSystem.getDisplay Path()</a>
258 <a href="#use-fileentry" class="anchor-link-icon" title="This feature mentio ned in 'Use FileEntry to write todos items to disk'">&#8593;</a>
259 </li>
260 <li>
261 <a href="/apps/fileSystem#method-restoreEntry" title="Read 'chrome.fileSyste m.restoreEntry()' in the Chrome developer docs">chrome.fileSystem.restoreEntry() </a>
262 <a href="#persistance" class="anchor-link-icon" title="This feature mentione d in 'Persist FileEntry objects'">&#8593;</a>
263 </li>
264 <li>
265 <a href="/apps/fileSystem#method-retainEntry" title="Read 'chrome.fileSystem .retainEntry()' in the Chrome developer docs">chrome.fileSystem.retainEntry()</a >
266 <a href="#persistance" class="anchor-link-icon" title="This feature mentione d in 'Persist FileEntry objects'">&#8593;</a>
267 </li>
268 </ul>
269
270 <p>Ready to continue onto the next step? Go to <a href="app_codelab_publish.html ">Step 7 - Publish your app &raquo;</a></p>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698