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

Side by Side Diff: chrome/browser/resources/uber/uber.js

Issue 9265020: [uber] make the navigation controls an iframe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: opt = Created 8 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/uber/uber.html ('k') | chrome/browser/resources/uber/uber_frame.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('uber', function() { 5 cr.define('uber', function() {
6 6
7 /** 7 /**
8 * Handles page initialization. 8 * Handles page initialization.
9 */ 9 */
10 function onLoad() { 10 function onLoad() {
11 var navigationItems = document.querySelectorAll('#navigation li');
12 var iframes = document.querySelectorAll('.iframe-container');
13
14 for (var i = 0; i < navigationItems.length; ++i) {
15 var navItem = navigationItems[i];
16 navItem.associatedIframe = iframes[i];
17 iframes[i].associatedNavItem = navItem;
18 navItem.addEventListener('click', onNavItemClicked);
19 }
20
21 // Update the URL if need be. 11 // Update the URL if need be.
22 if (window.location.pathname === '/') { 12 if (window.location.pathname === '/') {
23 var selectedNavItem = document.querySelector('#navigation li.selected'); 13 var pageId = getSelectedIframe().id;
24 var pageId = selectedNavItem.associatedIframe.id;
25 window.history.replaceState({pageId: pageId}, '', '/' + pageId); 14 window.history.replaceState({pageId: pageId}, '', '/' + pageId);
26 } 15 }
27 16
28 window.addEventListener('message', handleWindowMessage); 17 window.addEventListener('message', handleWindowMessage);
29 } 18 }
30 19
31 /** 20 /**
32 * Handles clicks on the navigation controls (switches the page and updates
33 * the URL).
34 * @param {Event} e The click event.
35 */
36 function onNavItemClicked(e) {
37 if (selectPageForNavItem(e.currentTarget)) {
38 var pageId = e.currentTarget.associatedIframe.id;
39 window.history.pushState({pageId: pageId}, '', '/' + pageId);
40 }
41 }
42
43 /**
44 * Selects the page for |navItem|, or does nothing if that item has already 21 * Selects the page for |navItem|, or does nothing if that item has already
45 * been selected. 22 * been selected.
46 * @param {Object} navItem The navigation control li. 23 * @param {Object} navItem The navigation control li.
47 * @return {boolean} True if the item became selected, false if it had already 24 * @return {boolean} True if the item became selected, false if it had already
48 * been selected. 25 * been selected.
49 */ 26 */
50 function selectPageForNavItem(navItem) { 27 function selectPageForNavItem(navItem) {
51 // Note that |iframe| is the containing element of the underlying iframe, as 28 // Note that |iframe| is the containing element of the underlying iframe, as
52 // opposed to the iframe element itself. 29 // opposed to the iframe element itself.
53 var iframe = navItem.associatedIframe; 30 var iframe = navItem.associatedIframe;
54 var currentIframe = getSelectedIframe_(); 31 var currentIframe = getSelectedIframe();
55 if (currentIframe == iframe) 32 if (currentIframe == iframe)
56 return false; 33 return false;
57 34
58 // Restore the cached title. 35 // Restore the cached title.
59 if (iframe.title) 36 if (iframe.title)
60 document.title = iframe.title; 37 document.title = iframe.title;
61 38
62 currentIframe.classList.remove('selected'); 39 currentIframe.classList.remove('selected');
63 iframe.classList.add('selected'); 40 iframe.classList.add('selected');
64 41
65 var currentNavItem = document.querySelector('li.selected'); 42 var currentNavItem = document.querySelector('li.selected');
66 currentNavItem.classList.remove('selected'); 43 currentNavItem.classList.remove('selected');
67 navItem.classList.add('selected'); 44 navItem.classList.add('selected');
68 45
69 return true; 46 return true;
70 } 47 }
71 48
72 /** 49 /**
73 * Handler for window.onpopstate. 50 * Handler for window.onpopstate.
74 * @param {Event} e The history event. 51 * @param {Event} e The history event.
75 */ 52 */
76 function onPopHistoryState(e) { 53 function onPopHistoryState(e) {
77 if (e.state && e.state.pageId) 54 if (e.state && e.state.pageId)
78 selectPageForNavItem($(e.state.pageId).associatedNavItem); 55 showPage(e.state.pageId);
79 } 56 }
80 57
81 /** 58 /**
82 * @return {Object} The currently selected iframe container. 59 * @return {Object} The currently selected iframe container.
83 * @private
84 */ 60 */
85 function getSelectedIframe_() { 61 function getSelectedIframe() {
86 return document.querySelector('.iframe-container.selected'); 62 return document.querySelector('.iframe-container.selected');
87 } 63 }
88 64
89 /** 65 /**
90 * Handles postMessage calls from the iframes of the contained pages. 66 * Handles postMessage calls from the iframes of the contained pages.
91 * 67 *
92 * The pages request functionality from this object by passing an object of 68 * The pages request functionality from this object by passing an object of
93 * the following form: 69 * the following form:
94 * 70 *
95 * { method : "methodToInvoke", 71 * { method : "methodToInvoke",
96 * params : {...} 72 * params : {...}
97 * } 73 * }
98 * 74 *
99 * |method| is required, while |params| is optional. Extra parameters required 75 * |method| is required, while |params| is optional. Extra parameters required
100 * by a method must be specified by that method's documentation. 76 * by a method must be specified by that method's documentation.
101 * 77 *
102 * @param {Event} e The posted object. 78 * @param {Event} e The posted object.
103 */ 79 */
104 function handleWindowMessage(e) { 80 function handleWindowMessage(e) {
105 if (e.data.method === 'showOverlay') 81 if (e.data.method === 'beginInterceptingEvents')
106 showOverlay_(); 82 backgroundNavigation();
107 else if (e.data.method === 'hideOverlay') 83 else if (e.data.method === 'stopInterceptingEvents')
108 hideOverlay_(); 84 foregroundNavigation();
109 else if (e.data.method === 'setTitle') 85 else if (e.data.method === 'setTitle')
110 setTitle_(e.origin, e.data.params); 86 setTitle_(e.origin, e.data.params);
87 else if (e.data.method === 'showPage')
88 showPage(e.data.params.pageId);
89 else if (e.data.method === 'navigationControlsLoaded')
90 onNavigationControlsLoaded();
111 else 91 else
112 console.error('Received unexpected message: ' + e.data); 92 console.error('Received unexpected message: ' + e.data);
113 } 93 }
114 94
115 /** 95 /**
116 * @private 96 * Sends the navigation iframe to the background.
117 */ 97 */
118 function showOverlay_() { 98 function backgroundNavigation() {
119 document.querySelector('.overlay').classList.add('showing'); 99 $('navigation').classList.add('background');
120 } 100 }
121 101
122 /** 102 /**
123 * @private 103 * Retrieves the navigation iframe from the background.
124 */ 104 */
125 function hideOverlay_() { 105 function foregroundNavigation() {
126 document.querySelector('.overlay').classList.remove('showing'); 106 $('navigation').classList.remove('background');
127 } 107 }
128 108
129 /** 109 /**
130 * Sets the title of the page. 110 * Sets the title of the page.
131 * @param {Object} origin The origin of the source iframe. 111 * @param {Object} origin The origin of the source iframe.
132 * @param {Object} params Must contain a |title| property. 112 * @param {Object} params Must contain a |title| property.
133 * @private
134 */ 113 */
135 function setTitle_(origin, params) { 114 function setTitle_(origin, params) {
136 // |iframe.src| always contains a trailing backslash while |origin| does not 115 // |iframe.src| always contains a trailing backslash while |origin| does not
137 // so add the trailing source for normalization. 116 // so add the trailing source for normalization.
138 var query = '.iframe-container > iframe[src="' + origin + '/"]'; 117 var query = '.iframe-container > iframe[src="' + origin + '/"]';
139 118
140 // Cache the title for the client iframe, i.e., the iframe setting the 119 // Cache the title for the client iframe, i.e., the iframe setting the
141 // title. querySelector returns the actual iframe element, so use parentNode 120 // title. querySelector returns the actual iframe element, so use parentNode
142 // to get back to the container. 121 // to get back to the container.
143 var container = document.querySelector(query).parentNode; 122 var container = document.querySelector(query).parentNode;
144 container.title = params.title; 123 container.title = params.title;
145 124
146 // Only update the currently displayed title if this is the visible frame. 125 // Only update the currently displayed title if this is the visible frame.
147 if (container == getSelectedIframe_()) 126 if (container == getSelectedIframe())
148 document.title = params.title; 127 document.title = params.title;
149 } 128 }
150 129
130 /**
131 * Selects a subpage. This is called from uber-frame.
132 * @param {String} pageId Should matche an id of one of the iframe containers.
133 */
134 function showPage(pageId) {
135 var container = $(pageId);
136 var lastSelected = document.querySelector('.iframe-container.selected');
137 if (lastSelected === container)
138 return;
139
140 lastSelected.classList.remove('selected');
141 container.classList.add('selected');
142 document.title = container.title;
143
144 window.history.pushState({pageId: pageId}, '', '/' + pageId);
145 updateNavigationControls();
146 }
147
148 function onNavigationControlsLoaded() {
149 updateNavigationControls();
150 }
151
152 /**
153 * Sends a message to uber-frame to update the appearance of the nav controls.
154 * It should be called whenever the selected iframe changes.
155 */
156 function updateNavigationControls() {
157 var iframe = getSelectedIframe();
158 uber.invokeMethodOnWindow($('navigation').firstChild.contentWindow,
159 'changeSelection', {pageId: iframe.id});
160 }
161
151 return { 162 return {
152 onLoad: onLoad, 163 onLoad: onLoad,
153 onPopHistoryState: onPopHistoryState 164 onPopHistoryState: onPopHistoryState
154 }; 165 };
155 166
156 }); 167 });
157 168
158 window.addEventListener('popstate', uber.onPopHistoryState); 169 window.addEventListener('popstate', uber.onPopHistoryState);
159 document.addEventListener('DOMContentLoaded', uber.onLoad); 170 document.addEventListener('DOMContentLoaded', uber.onLoad);
OLDNEW
« no previous file with comments | « chrome/browser/resources/uber/uber.html ('k') | chrome/browser/resources/uber/uber_frame.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698