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

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: 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
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
39 console.log('removing');
Dan Beam 2012/01/20 00:59:02 remove the removing
Evan Stade 2012/01/20 03:27:07 Done.
62 currentIframe.classList.remove('selected'); 40 currentIframe.classList.remove('selected');
63 iframe.classList.add('selected'); 41 iframe.classList.add('selected');
64 42
65 var currentNavItem = document.querySelector('li.selected'); 43 var currentNavItem = document.querySelector('li.selected');
66 currentNavItem.classList.remove('selected'); 44 currentNavItem.classList.remove('selected');
67 navItem.classList.add('selected'); 45 navItem.classList.add('selected');
68 46
69 return true; 47 return true;
70 } 48 }
71 49
72 /** 50 /**
73 * Handler for window.onpopstate. 51 * Handler for window.onpopstate.
74 * @param {Event} e The history event. 52 * @param {Event} e The history event.
75 */ 53 */
76 function onPopHistoryState(e) { 54 function onPopHistoryState(e) {
77 if (e.state && e.state.pageId) 55 if (e.state && e.state.pageId)
78 selectPageForNavItem($(e.state.pageId).associatedNavItem); 56 showPage(e.state.pageId);
79 } 57 }
80 58
81 /** 59 /**
82 * @return {Object} The currently selected iframe container. 60 * @return {Object} The currently selected iframe container.
83 * @private 61 * @private
csilv 2012/01/20 03:30:11 The naming change implies that this is no longer p
Evan Stade 2012/01/20 03:36:07 good catch, i should remove @private
84 */ 62 */
85 function getSelectedIframe_() { 63 function getSelectedIframe() {
86 return document.querySelector('.iframe-container.selected'); 64 return document.querySelector('.iframe-container.selected');
87 } 65 }
88 66
89 /** 67 /**
90 * Handles postMessage calls from the iframes of the contained pages. 68 * Handles postMessage calls from the iframes of the contained pages.
91 * 69 *
92 * The pages request functionality from this object by passing an object of 70 * The pages request functionality from this object by passing an object of
93 * the following form: 71 * the following form:
94 * 72 *
95 * { method : "methodToInvoke", 73 * { method : "methodToInvoke",
96 * params : {...} 74 * params : {...}
97 * } 75 * }
98 * 76 *
99 * |method| is required, while |params| is optional. Extra parameters required 77 * |method| is required, while |params| is optional. Extra parameters required
100 * by a method must be specified by that method's documentation. 78 * by a method must be specified by that method's documentation.
101 * 79 *
102 * @param {Event} e The posted object. 80 * @param {Event} e The posted object.
103 */ 81 */
104 function handleWindowMessage(e) { 82 function handleWindowMessage(e) {
105 if (e.data.method === 'showOverlay') 83 if (e.data.method === 'beginInterceptingEvents')
106 showOverlay_(); 84 backgroundNavigation();
107 else if (e.data.method === 'hideOverlay') 85 else if (e.data.method === 'stopInterceptingEvents')
108 hideOverlay_(); 86 foregroundNavigation();
109 else if (e.data.method === 'setTitle') 87 else if (e.data.method === 'setTitle')
110 setTitle_(e.origin, e.data.params); 88 setTitle_(e.origin, e.data.params);
89 else if (e.data.method === 'showPage')
90 showPage(e.data.params.pageId);
91 else if (e.data.method === 'navigationControlsLoaded')
92 onNavigationControlsLoaded();
111 else 93 else
112 console.error('Received unexpected message: ' + e.data); 94 console.error('Received unexpected message: ' + e.data);
113 } 95 }
114 96
115 /** 97 /**
116 * @private 98 * @private
117 */ 99 */
118 function showOverlay_() { 100 function backgroundNavigation() {
csilv 2012/01/20 03:30:11 Why remove the underscores on these two methods?
Evan Stade 2012/01/20 03:36:07 because they are not methods, they are functions
119 document.querySelector('.overlay').classList.add('showing'); 101 $('navigation').classList.add('background');
120 } 102 }
121 103
122 /** 104 /**
123 * @private 105 * @private
124 */ 106 */
125 function hideOverlay_() { 107 function foregroundNavigation() {
126 document.querySelector('.overlay').classList.remove('showing'); 108 $('navigation').classList.remove('background');
127 } 109 }
128 110
129 /** 111 /**
130 * Sets the title of the page. 112 * Sets the title of the page.
131 * @param {Object} origin The origin of the source iframe. 113 * @param {Object} origin The origin of the source iframe.
132 * @param {Object} params Must contain a |title| property. 114 * @param {Object} params Must contain a |title| property.
133 * @private 115 * @private
134 */ 116 */
135 function setTitle_(origin, params) { 117 function setTitle_(origin, params) {
136 // |iframe.src| always contains a trailing backslash while |origin| does not 118 // |iframe.src| always contains a trailing backslash while |origin| does not
137 // so add the trailing source for normalization. 119 // so add the trailing source for normalization.
138 var query = '.iframe-container > iframe[src="' + origin + '/"]'; 120 var query = '.iframe-container > iframe[src="' + origin + '/"]';
139 121
140 // Cache the title for the client iframe, i.e., the iframe setting the 122 // Cache the title for the client iframe, i.e., the iframe setting the
141 // title. querySelector returns the actual iframe element, so use parentNode 123 // title. querySelector returns the actual iframe element, so use parentNode
142 // to get back to the container. 124 // to get back to the container.
143 var container = document.querySelector(query).parentNode; 125 var container = document.querySelector(query).parentNode;
144 container.title = params.title; 126 container.title = params.title;
145 127
146 // Only update the currently displayed title if this is the visible frame. 128 // Only update the currently displayed title if this is the visible frame.
147 if (container == getSelectedIframe_()) 129 if (container == getSelectedIframe())
148 document.title = params.title; 130 document.title = params.title;
149 } 131 }
150 132
133 /**
134 * Selects a subpage. This is called from uber-frame.
135 * @param {String} pageId Should matche an id of one of the iframe containers.
136 */
137 function showPage(pageId) {
138 var container = $(pageId);
139 var lastSelected = document.querySelector('.iframe-container.selected');
140 if (lastSelected === container)
141 return;
142
143 console.log('removing');
Dan Beam 2012/01/20 00:59:02 here too
144 lastSelected.classList.remove('selected');
145 container.classList.add('selected');
146 document.title = container.title;
147
148 window.history.pushState({pageId: pageId}, '', '/' + pageId);
149 updateNavigationControls();
150 }
151
152 function onNavigationControlsLoaded() {
153 updateNavigationControls();
154 }
155
156 /**
157 * Sends a message to uber-frame to update the appearance of the nav controls.
158 * It should be called whenever the selected iframe changes.
159 */
160 function updateNavigationControls() {
161 var iframe = getSelectedIframe();
162 uber.invokeMethodOnWindow($('navigation').firstChild.contentWindow,
163 'changeSelection', {pageId: iframe.id});
164 }
165
151 return { 166 return {
152 onLoad: onLoad, 167 onLoad: onLoad,
153 onPopHistoryState: onPopHistoryState 168 onPopHistoryState: onPopHistoryState
154 }; 169 };
155 170
156 }); 171 });
157 172
158 window.addEventListener('popstate', uber.onPopHistoryState); 173 window.addEventListener('popstate', uber.onPopHistoryState);
159 document.addEventListener('DOMContentLoaded', uber.onLoad); 174 document.addEventListener('DOMContentLoaded', uber.onLoad);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698