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

Side by Side Diff: chrome/common/extensions/docs/templates/articles/app_codelab_webview.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="add-webview">
2 <span class="h1-step">Step 4:</span>
3 Open External Links With a Webview
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_step3</strong></em>.
9 </p>
10
11 <p>In this step, you will learn:</p>
12
13 <ul>
14 <li>How to show external web content inside your app in a secure and sandboxed way.</li>
15 </ul>
16
17 <p>
18 <em>Estimated time to complete this step: 10 minutes.</em>
19 <br>
20 To preview what you will complete in this step, <a href="#launch">jump down to the bottom of this page &#8595;</a>.
21 </p>
22
23 <h2 id="overview">Learn about the webview tag</h2>
24
25 <p>Some applications need to present external web content directly to the user b ut
26 keep them inside the application experience. For example, a news aggregator
27 might want to embed the news from external sites with all the formatting, images ,
28 and behavior of the original site. For these and other usages, Chrome Apps have
29 a custom HTML tag called <a href="/apps/tags/webview">webview</a>.</p>
30
31 <figure>
32 <img src="{{static}}/images/app_codelab/webview-example.png" alt="The Todo app using a webview">
33 </figure>
34
35 <p class="note">A webview is a sandboxed process. For example, the enclosing Chr ome App
36 (also known as the "embedder page") cannot easily access the webview's loaded DO M.
37 You can only interact with the webview using its API.</p>
38
39 <h2 id="implement-webview">Implement the webview tag</h2>
40
41 <p>Let's update our Todo app to search for URLs in the todo item text
42 in order to create a hyperlink. The link, when clicked, will open a new Chrome A pp window
43 (not a browser tab) with a webview presenting the content.</p>
44
45 <h3 id="update-permissions">Update permissions</h3>
46
47 <p>In <strong><em>manifest.json</em></strong>, request the <code>webview</code> permission:</p>
48
49 <pre data-filename="manifest.json">
50 "permissions": ["storage", "alarms", "notifications"<b>, "webview"</b>],
51 </pre>
52
53 <h3 id="create-webview">Create a webview embedder page</h3>
54
55 <p>Create a new file in the root of your project folder and name it <strong><em> webview.html</em></strong>.
56 This file is a basic webpage with one <code>&lt;webview&gt;</code> tag:</p>
57
58 <pre data-filename="webview.html">
59 <b>&lt;!DOCTYPE html&gt;
60 &lt;html&gt;
61 &lt;head&gt;
62 &lt;meta charset="utf-8"&gt;
63 &lt;/head&gt;
64 &lt;body&gt;
65 &lt;webview style="width: 100%; height: 100%;"&gt;&lt;/webview&gt;
66 &lt;/body&gt;
67 &lt;/html&gt;</b>
68 </pre>
69
70 <h3 id="parse-urls">Parse for URLs in todo items</h3>
71
72 <p>At the end of <strong><em>controller.js</em></strong>, add a new method calle d <code>_parseForURLs()</code>:</p>
73
74 <pre data-filename="controller.js">
75 Controller.prototype._getCurrentPage = function () {
76 return document.location.hash.split('/')[1];
77 };
78
79 <b>Controller.prototype._parseForURLs = function (text) {</b>
80 <b> var re = /(https?:\/\/[^\s"&lt;&gt;,]+)/g;</b>
81 <b> return text.replace(re, '&lt;a href="$1" data-src="$1"&gt;$1&lt;/a&gt;'); </b>
82 <b>};</b>
83
84 // Export to window
85 window.app.Controller = Controller;
86 })(window);
87 </pre>
88
89 <p>Whenever a string starting with "http://" or "https://" is found, a HTML anch or tag will be created to wrap around the URL.</p>
90
91 <h3 id="render-links">Render hyperlinks in the todo list</h3>
92
93 <p>Find <code>showAll()</code> in <em>controller.js</em>. Update <code>showAll() </code>
94 to parse for links by using the <code>_parseForURLs()</code> method that we adde d previously:</p>
95
96 <pre data-filename="controller.js">
97 /**
98 * An event to fire on load. Will get all items and display them in the
99 * todo-list
100 */
101 Controller.prototype.showAll = function () {
102 this.model.read(function (data) {
103 <strike>this.$todoList.innerHTML = this.view.show(data);</strike>
104 <b>this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));</b>
105 }.bind(this));
106 };
107 </pre>
108
109 <p>Do the same for <code>showActive()</code> and <code>showCompleted()</code>:</ p>
110
111 <pre data-filename="controller.js">
112 /**
113 * Renders all active tasks
114 */
115 Controller.prototype.showActive = function () {
116 this.model.read({ completed: 0 }, function (data) {
117 <strike>this.$todoList.innerHTML = this.view.show(data);</strike>
118 <b>this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));</b>
119 }.bind(this));
120 };
121
122 /**
123 * Renders all completed tasks
124 */
125 Controller.prototype.showCompleted = function () {
126 this.model.read({ completed: 1 }, function (data) {
127 <strike>this.$todoList.innerHTML = this.view.show(data);</strike>
128 <b>this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));</b>
129 }.bind(this));
130 };
131 </pre>
132
133 <p>And finally, add <code>_parseForURLs()</code> to <code>editItem()</code>:</p>
134
135 <pre data-filename="controller.js">
136 Controller.prototype.editItem = function (id, label) {
137 ...
138 var onSaveHandler = function () {
139 ...
140 // Instead of re-rendering the whole view just update
141 // this piece of it
142 <strike>label.innerHTML = value;</strike>
143 <b>label.innerHTML = this._parseForURLs(value);</b>
144 ...
145 }.bind(this);
146 ...
147 }
148 </pre>
149
150 <p>Still in <code>editItem()</code>, fix the code so that it uses the
151 <code>innerText</code> of the label instead of the label's <code>innerHTML</code >:</p>
152
153 <pre data-filename="controller.js">
154 Controller.prototype.editItem = function (id, label) {
155 ...
156 // Get the <strike>innerHTML</strike> <b>innerText</b> of the label instead of requesting the data from the
157 // ORM. If this were a real DB this would save a lot of time and would avoid
158 // a spinner gif.
159 <strike>input.value = label.innerHTML;</strike>
160 <b>input.value = label.innerText;</b>
161 ...
162 }
163 </pre>
164
165 <h3 id="open-webview">Open new window containing webview</h3>
166
167 <p>Add a <code>_doShowUrl()</code> method to <em>controller.js</em>. This method will open a new Chrome App window
168 via <a href="/apps/app_window.html#method-create">chrome.app.window.create()</a>
169 with <em>webview.html</em> as the window source:</p>
170
171 <pre data-filename="controller.js">
172 Controller.prototype._parseForURLs = function (text) {
173 var re = /(https?:\/\/[^\s"&lt;&gt;,]+)/g;
174 return text.replace(re, '&lt;a href="$1" data-src="$1"&gt;$1&lt;/a&gt;');
175 };
176
177 <b>Controller.prototype._doShowUrl = function(e) {</b>
178 <b> // only applies to elements with data-src attributes</b>
179 <b> if (!e.target.hasAttribute('data-src')) {</b>
180 <b> return;</b>
181 <b> }</b>
182 <b> e.preventDefault();</b>
183 <b> var url = e.target.getAttribute('data-src');</b>
184 <b> chrome.app.window.create(</b>
185 <b> 'webview.html',</b>
186 <b> {hidden: true}, // only show window when webview is configured</b>
187 <b> function(appWin) {</b>
188 <b> appWin.contentWindow.addEventListener('DOMContentLoaded',</b>
189 <b> function(e) {</b>
190 <b> // when window is loaded, set webview source</b>
191 <b> var webview = appWin.contentWindow.</b>
192 <b> document.querySelector('webview');</b>
193 <b> webview.src = url;</b>
194 <b> // now we can show it:</b>
195 <b> appWin.show();</b>
196 <b> }</b>
197 <b> );</b>
198 <b> });</b>
199 <b>};</b>
200
201 // Export to window
202 window.app.Controller = Controller;
203 })(window);
204
205 </pre>
206
207 <p>In the <code>chrome.app.window.create()</code> callback, note how the webview 's URL is set via the <a href="/apps/tags/webview#tag"><code>src</code> tag attr ibute</a>.</p>
208
209 <p>Lastly, add a click event listener inside the <code>Controller</code> constru ctor to call
210 <code>doShowUrl()</code> when a user clicks on a link:</p>
211
212 <pre data-filename="controller.js">
213 function Controller(model, view) {
214 ...
215 this.router = new Router();
216 this.router.init();
217
218 <b>this.$todoList.addEventListener('click', this._doShowUrl);</b>
219
220 window.addEventListener('load', function () {
221 this._updateFilterState();
222 }.bind(this));
223 ...
224 }
225 </pre>
226
227 <h2 id="launch">Launch your finished Todo app</h2>
228
229 <p>You are done Step 4! If you reload your app and add a todo item with a full U RL
230 starting with http:// or https://, you should see something like this:</p>
231
232 <figure>
233 <img src="{{static}}/images/app_codelab/step4-completed.gif" alt="The Todo app with webview"/>
234 </figure>
235
236 <h2 id="recap">Recap APIs referenced in this step</h2>
237
238 <p>For more detailed information about some of the APIs introduced in this step, refer to:</p>
239
240 <ul>
241 <li>
242 <a href="/apps/declare_permissions" title="Read 'Declare Permissions' in the Chrome developer docs">Declare Permissions</a>
243 <a href="#update-permissions" class="anchor-link-icon" title="This feature m entioned in 'Update app permissions'">&#8593;</a>
244 </li>
245 <li>
246 <a href="/apps/tags/webview" title="Read '&lt;webview&gt; Tag' in the Chrome developer docs">&lt;webview&gt; Tag</a>
247 <a href="#overview" class="anchor-link-icon" title="This feature mentioned i n 'Learn about the webview tag'">&#8593;</a>
248 <a href="#create-webview" class="anchor-link-icon" title="This feature menti oned in 'Create a webview embedder page'">&#8593;</a>
249 </li>
250 <li>
251 <a href="/apps/app_window.html#method-create" title="Read 'chrome.app.window .create()' in the Chrome developer docs">chrome.app.window.create()</a>
252 <a href="#open-webview" class="anchor-link-icon" title="This feature mention ed in 'Open new window containing webview'">&#8593;</a>
253 </li>
254 <li>
255 <a href="/apps/tags/webview#tag" title="Read '&lt;webview&gt; Tag attributes ' in the Chrome developer docs">&lt;webview&gt; Tag attributes</a>
256 <a href="#open-webview" class="anchor-link-icon" title="This feature mention ed in 'Open new window containing webview'">&#8593;</a>
257 </li>
258
259 </ul>
260
261 <p>Ready to continue onto the next step? Go to <a href="app_codelab_images.html" >Step 5 - Add images from the web &raquo;</a></p>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698