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 3// found in the LICENSE file. 4 5// This file contains the navigation controls that are visible on the left side 6// of the uber page. It exists separately from uber.js so that it may be loaded 7// in an iframe. Iframes can be layered on top of each other, but not mixed in 8// with page content, so all overlapping content on uber must be framed. 9 10<include src="../../../../ui/webui/resources/js/util.js"></include> 11<include src="uber_utils.js"></include> 12 13cr.define('uber_frame', function() { 14 15 /** 16 * Handles page initialization. 17 */ 18 function onLoad() { 19 var navigationItems = document.querySelectorAll('li'); 20 21 for (var i = 0; i < navigationItems.length; ++i) { 22 navigationItems[i].addEventListener('click', onNavItemClicked); 23 } 24 25 window.addEventListener('message', handleWindowMessage); 26 uber.invokeMethodOnParent('navigationControlsLoaded'); 27 28 document.documentElement.addEventListener('mousewheel', onMouseWheel); 29 cr.ui.FocusManager.disableMouseFocusOnButtons(); 30 } 31 32 /** 33 * Handles clicks on the navigation controls (switches the page and updates 34 * the URL). 35 * @param {Event} e The click event. 36 */ 37 function onNavItemClicked(e) { 38 // Though pointer-event: none; is applied to the .selected nav item, users 39 // can still tab to them and press enter/space which simulates a click. 40 if (e.target.classList.contains('selected')) 41 return; 42 43 // Extensions can override Uber content (e.g., if the user has a history 44 // extension, it should display when the 'History' navigation is clicked). 45 if (e.currentTarget.getAttribute('override') == 'yes') { 46 window.open('chrome://' + e.currentTarget.getAttribute('controls'), 47 '_blank'); 48 return; 49 } 50 51 uber.invokeMethodOnParent('showPage', 52 {pageId: e.currentTarget.getAttribute('controls')}); 53 54 setSelection(e.currentTarget); 55 } 56 57 /** 58 * Handles postMessage from chrome://chrome. 59 * @param {Event} e The post data. 60 */ 61 function handleWindowMessage(e) { 62 if (e.data.method === 'changeSelection') 63 changeSelection(e.data.params); 64 else if (e.data.method === 'adjustToScroll') 65 adjustToScroll(e.data.params); 66 else if (e.data.method === 'setContentChanging') 67 setContentChanging(e.data.params); 68 else 69 console.error('Received unexpected message', e.data); 70 } 71 72 /** 73 * Changes the selected nav control. 74 * @param {Object} params Must contain pageId. 75 */ 76 function changeSelection(params) { 77 var navItem = 78 document.querySelector('li[controls="' + params.pageId + '"]'); 79 setSelection(navItem); 80 } 81 82 /** 83 * Sets selection on the given nav item. 84 * @param {boolean} newSelection The item to be selected. 85 */ 86 function setSelection(newSelection) { 87 var lastSelectedNavItem = document.querySelector('li.selected'); 88 if (lastSelectedNavItem !== newSelection) { 89 newSelection.classList.add('selected'); 90 if (lastSelectedNavItem) 91 lastSelectedNavItem.classList.remove('selected'); 92 } 93 } 94 95 /** 96 * Adjusts this frame's content to scrolls from the outer frame. This is done 97 * to obscure text in RTL as a user scrolls over the content of this frame (as 98 * currently RTL scrollbars still draw on the right). 99 * @param {number} scroll document.body.scrollLeft of the content frame. 100 */ 101 function adjustToScroll(scrollLeft) { 102 assert(isRTL()); 103 document.body.style.webkitTransform = 'translateX(' + -scrollLeft + 'px)'; 104 } 105 106 /** 107 * Enable/disable an animation to ease the nav bar back into view when 108 * changing content while horizontally scrolled. 109 * @param {boolean} enabled Whether easing should be enabled. 110 */ 111 function setContentChanging(enabled) { 112 assert(isRTL()); 113 document.documentElement.classList[enabled ? 'add' : 'remove']( 114 'changing-content'); 115 } 116 117 /** 118 * Handles mouse wheels on the top level element. Forwards them to uber.js. 119 * @param {Event} e The mouse wheel event. 120 */ 121 function onMouseWheel(e) { 122 uber.invokeMethodOnParent('mouseWheel', 123 {deltaX: e.wheelDeltaX, deltaY: e.wheelDeltaY}); 124 } 125 126 /** 127 * @return {Object} The currently selected iframe container. 128 * @private 129 */ 130 function getSelectedIframe() { 131 return document.querySelector('.iframe-container.selected'); 132 } 133 134 /** 135 * Finds the <li> element whose 'controls' attribute is |controls| and sets 136 * its 'override' attribute to |override|. 137 * @param {string} controls The value of the 'controls' attribute of the 138 * element to change. 139 * @param {string} override The value to set for the 'override' attribute of 140 * that element (either 'yes' or 'no'). 141 */ 142 function setNavigationOverride(controls, override) { 143 var navItem = 144 document.querySelector('li[controls="' + controls + '"]'); 145 navItem.setAttribute('override', override); 146 } 147 148 return { 149 onLoad: onLoad, 150 setNavigationOverride: setNavigationOverride, 151 }; 152 153}); 154 155document.addEventListener('DOMContentLoaded', uber_frame.onLoad); 156