15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cr.define('cr.ui.pageManager', function() { 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var PageManager = cr.ui.pageManager.PageManager; 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Base class for pages that can be shown and hidden by PageManager. Each Page 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * is like a node in a forest, corresponding to a particular div. At any 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * point, one root Page is visible, and any visible Page can show a child Page 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * as an overlay. The host of the root Page(s) should provide a container div 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * for each nested level to enforce the stack order of overlays. 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @constructor 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {string} name Page name. 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {string} title Page title, used for history. 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {string} pageDivName ID of the div corresponding to the page. 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @extends {cr.EventTarget} 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function Page(name, title, pageDivName) { 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.name = name; 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.title = title; 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDivName = pageDivName; 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv = $(this.pageDivName); 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |pageDiv.page| is set to the page object (this) when the page is visible 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // to track which page is being shown when multiple pages can share the same 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // underlying div. 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv.page = null; 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.tab = null; 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.lastFocusedElement = null; 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.hash = ''; 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Page.prototype = { 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) __proto__: cr.EventTarget.prototype, 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * The parent page of this page, or null for root pages. 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @type {cr.ui.pageManager.Page} 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parentPage: null, 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * The section on the parent page that is associated with this page. 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Can be null. 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {Element} 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) associatedSection: null, 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * An array of controls that are associated with this page. The first 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * control should be located on a root page. 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {Array.<Element>} 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) associatedControls: null, 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * If true, this page should always be considered the top-most page when 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * visible. 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {boolean} 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) alwaysOnTop_: false, 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Initializes page content. 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) initializePage: function() {}, 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Called by the PageManager when this.hash changes while the page is 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * already visible. This is analogous to the hashchange DOM event. 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci didChangeHash: function() {}, 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Sets focus on the first focusable element. Override for a custom focus 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * strategy. 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) focus: function() { 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Do not change focus if any control on this page is already focused. 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.pageDiv.contains(document.activeElement)) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var elements = this.pageDiv.querySelectorAll( 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'input, list, select, textarea, button'); 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (var i = 0; i < elements.length; i++) { 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var element = elements[i]; 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Try to focus. If fails, then continue. 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) element.focus(); 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (document.activeElement == element) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Reverses the child elements of this overlay's button strip if it hasn't 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * already been reversed. This is necessary because WebKit does not alter 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * the tab order for elements that are visually reversed using 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * flex-direction: reverse, and the button order is reversed for views. 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * See http://webk.it/62664 for more information. 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reverseButtonStrip: function() { 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert(this.isOverlay); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var buttonStrips = 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv.querySelectorAll('.button-strip:not([reversed])'); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Reverse all button-strips in the overlay. 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (var j = 0; j < buttonStrips.length; j++) { 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var buttonStrip = buttonStrips[j]; 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var childNodes = buttonStrip.childNodes; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (var i = childNodes.length - 1; i >= 0; i--) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buttonStrip.appendChild(childNodes[i]); 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buttonStrip.setAttribute('reversed', ''); 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Whether it should be possible to show the page. 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @return {boolean} True if the page should be shown. 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) canShowPage: function() { 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Updates the hash of the current page. If the page is topmost, the history 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * state is updated. 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {string} hash The new hash value. Like location.hash, this 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * should include the leading '#' if not empty. 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci setHash: function(hash) { 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (this.hash == hash) 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.hash = hash; 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PageManager.onPageHashChanged(this); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }, 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Called after the page has been shown. 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci didShowPage: function() {}, 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Called before the page will be hidden, e.g., when a different root page 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * will be shown. 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci willHidePage: function() {}, 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Called after the overlay has been closed. 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci didClosePage: function() {}, 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Gets the container div for this page if it is an overlay. 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {HTMLDivElement} 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) get container() { 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert(this.isOverlay); 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this.pageDiv.parentNode; 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Gets page visibility state. 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {boolean} 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) get visible() { 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If this is an overlay dialog it is no longer considered visible while 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the overlay is fading out. See http://crbug.com/118629. 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.isOverlay && 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.container.classList.contains('transparent')) { 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.pageDiv.hidden) 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this.pageDiv.page == this; 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Sets page visibility. 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {boolean} 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) set visible(visible) { 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((this.visible && visible) || (!this.visible && !visible)) 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If using an overlay, the visibility of the dialog is toggled at the 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // same time as the overlay to show the dialog's out transition. This 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is handled in setOverlayVisible. 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.isOverlay) { 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.setOverlayVisible_(visible); 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv.page = this; 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv.hidden = !visible; 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PageManager.onPageVisibilityChanged(this); 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cr.dispatchPropertyChange(this, 'visible', visible, !visible); 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Whether the page is considered 'sticky', such that it will remain a root 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * page even if sub-pages change. 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {boolean} True if this page is sticky. 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) get sticky() { 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {boolean} True if this page should always be considered the 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * top-most page when visible. 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) get alwaysOnTop() { 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this.alwaysOnTop_; 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @type {boolean} True if this page should always be considered the 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * top-most page when visible. Only overlays can be always on top. 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) set alwaysOnTop(value) { 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert(this.isOverlay); 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.alwaysOnTop_ = value; 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Shows or hides an overlay (including any visible dialog). 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @param {boolean} visible Whether the overlay should be visible or not. 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @private 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) setOverlayVisible_: function(visible) { 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert(this.isOverlay); 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var pageDiv = this.pageDiv; 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var container = this.container; 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (container.hidden != visible) { 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (visible) { 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the container is set hidden and then immediately set visible 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // again, the fadeCompleted_ callback would cause it to be erroneously 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // hidden again. Removing the transparent tag avoids that. 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.classList.remove('transparent'); 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Hide all dialogs in this container since a different one may have 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // been previously visible before fading out. 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var pages = container.querySelectorAll('.page'); 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (var i = 0; i < pages.length; i++) 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pages[i].hidden = true; 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Show the new dialog. 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pageDiv.hidden = false; 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pageDiv.page = this; 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var self = this; 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var loading = PageManager.isLoading(); 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!loading) { 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(flackr): Use an event delegate to avoid having to subscribe and 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // unsubscribe for webkitTransitionEnd events. 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.addEventListener('webkitTransitionEnd', function f(e) { 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var propName = e.propertyName; 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (e.target != e.currentTarget || 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (propName && propName != 'opacity')) { 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.removeEventListener('webkitTransitionEnd', f); 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.fadeCompleted_(); 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }); 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // -webkit-transition is 200ms. Let's wait for 400ms. 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ensureTransitionEndEvent(container, 400); 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (visible) { 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.hidden = false; 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pageDiv.hidden = false; 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pageDiv.page = this; 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // NOTE: This is a hacky way to force the container to layout which 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // will allow us to trigger the webkit transition. 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** @suppress {uselessCode} */ 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.scrollTop; 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv.removeAttribute('aria-hidden'); 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.parentPage) { 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.parentPage.pageDiv.parentElement.setAttribute('aria-hidden', 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) true); 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.classList.remove('transparent'); 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PageManager.onPageVisibilityChanged(this); 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Kick change events for text fields. 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pageDiv.contains(document.activeElement)) 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) document.activeElement.blur(); 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) container.classList.add('transparent'); 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (loading) 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.fadeCompleted_(); 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /** 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Called when a container opacity transition finishes. 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * @private 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fadeCompleted_: function() { 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.container.classList.contains('transparent')) { 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.pageDiv.hidden = true; 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.container.hidden = true; 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (this.parentPage) 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this.parentPage.pageDiv.parentElement.removeAttribute('aria-hidden'); 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PageManager.onPageVisibilityChanged(this); 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }, 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Export 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return { 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Page: Page 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}); 325