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

Unified Diff: chrome/common/extensions/docs/templates/articles/app_codelab_webview.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_codelab_webview.html
diff --git a/chrome/common/extensions/docs/templates/articles/app_codelab_webview.html b/chrome/common/extensions/docs/templates/articles/app_codelab_webview.html
new file mode 100644
index 0000000000000000000000000000000000000000..e4dcaac1445a43091bad341c3016cb347e2f2279
--- /dev/null
+++ b/chrome/common/extensions/docs/templates/articles/app_codelab_webview.html
@@ -0,0 +1,261 @@
+<h1 id="add-webview">
+ <span class="h1-step">Step 4:</span>
+ Open External Links With a Webview
+</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_step3</strong></em>.
+</p>
+
+<p>In this step, you will learn:</p>
+
+<ul>
+ <li>How to show external web content inside your app in a secure and sandboxed way.</li>
+</ul>
+
+<p>
+ <em>Estimated time to complete this step: 10 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="overview">Learn about the webview tag</h2>
+
+<p>Some applications need to present external web content directly to the user but
+keep them inside the application experience. For example, a news aggregator
+might want to embed the news from external sites with all the formatting, images,
+and behavior of the original site. For these and other usages, Chrome Apps have
+a custom HTML tag called <a href="/apps/tags/webview">webview</a>.</p>
+
+<figure>
+ <img src="{{static}}/images/app_codelab/webview-example.png" alt="The Todo app using a webview">
+</figure>
+
+<p class="note">A webview is a sandboxed process. For example, the enclosing Chrome App
+(also known as the "embedder page") cannot easily access the webview's loaded DOM.
+You can only interact with the webview using its API.</p>
+
+<h2 id="implement-webview">Implement the webview tag</h2>
+
+<p>Let's update our Todo app to search for URLs in the todo item text
+in order to create a hyperlink. The link, when clicked, will open a new Chrome App window
+(not a browser tab) with a webview presenting the content.</p>
+
+<h3 id="update-permissions">Update permissions</h3>
+
+<p>In <strong><em>manifest.json</em></strong>, request the <code>webview</code> permission:</p>
+
+<pre data-filename="manifest.json">
+"permissions": ["storage", "alarms", "notifications"<b>, "webview"</b>],
+</pre>
+
+<h3 id="create-webview">Create a webview embedder page</h3>
+
+<p>Create a new file in the root of your project folder and name it <strong><em>webview.html</em></strong>.
+This file is a basic webpage with one <code>&lt;webview&gt;</code> tag:</p>
+
+<pre data-filename="webview.html">
+<b>&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+&lt;/head&gt;
+&lt;body&gt;
+ &lt;webview style="width: 100%; height: 100%;"&gt;&lt;/webview&gt;
+&lt;/body&gt;
+&lt;/html&gt;</b>
+</pre>
+
+<h3 id="parse-urls">Parse for URLs in todo items</h3>
+
+<p>At the end of <strong><em>controller.js</em></strong>, add a new method called <code>_parseForURLs()</code>:</p>
+
+<pre data-filename="controller.js">
+ Controller.prototype._getCurrentPage = function () {
+ return document.location.hash.split('/')[1];
+ };
+
+ <b>Controller.prototype._parseForURLs = function (text) {</b>
+ <b> var re = /(https?:\/\/[^\s"&lt;&gt;,]+)/g;</b>
+ <b> return text.replace(re, '&lt;a href="$1" data-src="$1"&gt;$1&lt;/a&gt;');</b>
+ <b>};</b>
+
+ // Export to window
+ window.app.Controller = Controller;
+})(window);
+</pre>
+
+<p>Whenever a string starting with "http://" or "https://" is found, a HTML anchor tag will be created to wrap around the URL.</p>
+
+<h3 id="render-links">Render hyperlinks in the todo list</h3>
+
+<p>Find <code>showAll()</code> in <em>controller.js</em>. Update <code>showAll()</code>
+to parse for links by using the <code>_parseForURLs()</code> method that we added previously:</p>
+
+<pre data-filename="controller.js">
+/**
+ * An event to fire on load. Will get all items and display them in the
+ * todo-list
+ */
+Controller.prototype.showAll = function () {
+ this.model.read(function (data) {
+ <strike>this.$todoList.innerHTML = this.view.show(data);</strike>
+ <b>this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));</b>
+ }.bind(this));
+};
+</pre>
+
+<p>Do the same for <code>showActive()</code> and <code>showCompleted()</code>:</p>
+
+<pre data-filename="controller.js">
+/**
+ * Renders all active tasks
+ */
+Controller.prototype.showActive = function () {
+ this.model.read({ completed: 0 }, function (data) {
+ <strike>this.$todoList.innerHTML = this.view.show(data);</strike>
+ <b>this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));</b>
+ }.bind(this));
+};
+
+/**
+ * Renders all completed tasks
+ */
+Controller.prototype.showCompleted = function () {
+ this.model.read({ completed: 1 }, function (data) {
+ <strike>this.$todoList.innerHTML = this.view.show(data);</strike>
+ <b>this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));</b>
+ }.bind(this));
+};
+</pre>
+
+<p>And finally, add <code>_parseForURLs()</code> to <code>editItem()</code>:</p>
+
+<pre data-filename="controller.js">
+Controller.prototype.editItem = function (id, label) {
+ ...
+ var onSaveHandler = function () {
+ ...
+ // Instead of re-rendering the whole view just update
+ // this piece of it
+ <strike>label.innerHTML = value;</strike>
+ <b>label.innerHTML = this._parseForURLs(value);</b>
+ ...
+ }.bind(this);
+ ...
+}
+</pre>
+
+<p>Still in <code>editItem()</code>, fix the code so that it uses the
+<code>innerText</code> of the label instead of the label's <code>innerHTML</code>:</p>
+
+<pre data-filename="controller.js">
+Controller.prototype.editItem = function (id, label) {
+ ...
+ // Get the <strike>innerHTML</strike> <b>innerText</b> of the label instead of requesting the data from the
+ // ORM. If this were a real DB this would save a lot of time and would avoid
+ // a spinner gif.
+ <strike>input.value = label.innerHTML;</strike>
+ <b>input.value = label.innerText;</b>
+ ...
+}
+</pre>
+
+<h3 id="open-webview">Open new window containing webview</h3>
+
+<p>Add a <code>_doShowUrl()</code> method to <em>controller.js</em>. This method will open a new Chrome App window
+via <a href="/apps/app_window.html#method-create">chrome.app.window.create()</a>
+with <em>webview.html</em> as the window source:</p>
+
+<pre data-filename="controller.js">
+ Controller.prototype._parseForURLs = function (text) {
+ var re = /(https?:\/\/[^\s"&lt;&gt;,]+)/g;
+ return text.replace(re, '&lt;a href="$1" data-src="$1"&gt;$1&lt;/a&gt;');
+ };
+
+ <b>Controller.prototype._doShowUrl = function(e) {</b>
+ <b> // only applies to elements with data-src attributes</b>
+ <b> if (!e.target.hasAttribute('data-src')) {</b>
+ <b> return;</b>
+ <b> }</b>
+ <b> e.preventDefault();</b>
+ <b> var url = e.target.getAttribute('data-src');</b>
+ <b> chrome.app.window.create(</b>
+ <b> 'webview.html',</b>
+ <b> {hidden: true}, // only show window when webview is configured</b>
+ <b> function(appWin) {</b>
+ <b> appWin.contentWindow.addEventListener('DOMContentLoaded',</b>
+ <b> function(e) {</b>
+ <b> // when window is loaded, set webview source</b>
+ <b> var webview = appWin.contentWindow.</b>
+ <b> document.querySelector('webview');</b>
+ <b> webview.src = url;</b>
+ <b> // now we can show it:</b>
+ <b> appWin.show();</b>
+ <b> }</b>
+ <b> );</b>
+ <b> });</b>
+ <b>};</b>
+
+ // Export to window
+ window.app.Controller = Controller;
+})(window);
+
+</pre>
+
+<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 attribute</a>.</p>
+
+<p>Lastly, add a click event listener inside the <code>Controller</code> constructor to call
+<code>doShowUrl()</code> when a user clicks on a link:</p>
+
+<pre data-filename="controller.js">
+function Controller(model, view) {
+ ...
+ this.router = new Router();
+ this.router.init();
+
+ <b>this.$todoList.addEventListener('click', this._doShowUrl);</b>
+
+ window.addEventListener('load', function () {
+ this._updateFilterState();
+ }.bind(this));
+ ...
+}
+</pre>
+
+<h2 id="launch">Launch your finished Todo app</h2>
+
+<p>You are done Step 4! If you reload your app and add a todo item with a full URL
+starting with http:// or https://, you should see something like this:</p>
+
+<figure>
+ <img src="{{static}}/images/app_codelab/step4-completed.gif" alt="The Todo app with webview"/>
+</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/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 app permissions'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/tags/webview" title="Read '&lt;webview&gt; Tag' in the Chrome developer docs">&lt;webview&gt; Tag</a>
+ <a href="#overview" class="anchor-link-icon" title="This feature mentioned in 'Learn about the webview tag'">&#8593;</a>
+ <a href="#create-webview" class="anchor-link-icon" title="This feature mentioned in 'Create a webview embedder page'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/app_window.html#method-create" title="Read 'chrome.app.window.create()' in the Chrome developer docs">chrome.app.window.create()</a>
+ <a href="#open-webview" class="anchor-link-icon" title="This feature mentioned in 'Open new window containing webview'">&#8593;</a>
+ </li>
+ <li>
+ <a href="/apps/tags/webview#tag" title="Read '&lt;webview&gt; Tag attributes' in the Chrome developer docs">&lt;webview&gt; Tag attributes</a>
+ <a href="#open-webview" class="anchor-link-icon" title="This feature mentioned in 'Open new window containing webview'">&#8593;</a>
+ </li>
+
+</ul>
+
+<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>

Powered by Google App Engine
This is Rietveld 408576698