// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. cr.define('options', function() { ///////////////////////////////////////////////////////////////////////////// // OptionsPage class: /** * Base class for options page. * @constructor * @param {string} name Options page name, also defines id of the div element * containing the options view and the name of options page navigation bar * item as name+'PageNav'. * @param {string} title Options page title, used for navigation bar * @extends {EventTarget} */ function OptionsPage(name, title, pageDivName) { this.name = name; this.title = title; this.pageDivName = pageDivName; this.pageDiv = $(this.pageDivName); this.tab = null; this.managed = false; } OptionsPage.registeredPages_ = {}; /** * Pages which are meant to have an entry in the nav, but * not have a permanent entry. */ OptionsPage.registeredSubPages_ = {}; /** * Pages which are meant to behave like modal dialogs. */ OptionsPage.registeredOverlayPages_ = {}; /** * Shows a registered page. * @param {string} pageName Page name. */ OptionsPage.showPageByName = function(pageName) { for (var name in OptionsPage.registeredPages_) { var page = OptionsPage.registeredPages_[name]; page.visible = name == pageName; } }; /** * Called on load. Dispatch the URL hash to the given page's handleHash * function. * @param {string} pageName The string name of the (registered) options page. * @param {string} hash The value of the hash component of the URL. */ OptionsPage.handleHashForPage = function(pageName, hash) { OptionsPage.registeredPages_[pageName].handleHash(hash); }; /** * Shows a registered Overlay page. * @param {string} overlayName Page name. */ OptionsPage.showOverlay = function(overlayName) { if (OptionsPage.registeredOverlayPages_[overlayName]) { OptionsPage.registeredOverlayPages_[overlayName].visible = true; } }; /** * Clears overlays (i.e. hide all overlays). */ OptionsPage.clearOverlays = function() { for (var name in OptionsPage.registeredOverlayPages_) { var page = OptionsPage.registeredOverlayPages_[name]; page.visible = false; } }; /** * Clears overlays if the key event is ESC. * @param {Event} e Key event. * @private */ OptionsPage.clearOverlaysOnEsc_ = function(e) { if (e.keyCode == 27) { // Esc OptionsPage.clearOverlays(); } }; /** * Shows the tab contents for the given navigation tab. * @param {!Element} tab The tab that the user clicked. */ OptionsPage.showTab = function(tab) { if (!tab.classList.contains('inactive-tab')) return; if (this.activeNavTab != null) { this.activeNavTab.classList.remove('active-tab'); $(this.activeNavTab.getAttribute('tab-contents')).classList. remove('active-tab-contents'); } tab.classList.add('active-tab'); $(tab.getAttribute('tab-contents')).classList.add('active-tab-contents'); this.activeNavTab = tab; } /** * Registers new options page. * @param {OptionsPage} page Page to register. */ OptionsPage.register = function(page) { OptionsPage.registeredPages_[page.name] = page; // Create and add new page
  • element to navbar. var pageNav = document.createElement('li'); pageNav.id = page.name + 'PageNav'; pageNav.className = 'navbar-item'; pageNav.setAttribute('pageName', page.name); pageNav.textContent = page.title; pageNav.tabIndex = 0; pageNav.onclick = function(event) { OptionsPage.showPageByName(this.getAttribute('pageName')); }; pageNav.onkeypress = function(event) { // Enter or space if (event.keyCode == 13 || event.keyCode == 32) { OptionsPage.showPageByName(this.getAttribute('pageName')); } }; var navbar = $('navbar'); navbar.appendChild(pageNav); page.tab = pageNav; page.initializePage(); }; /** * Registers a new Sub tab page. * @param {OptionsPage} page Page to register. */ OptionsPage.registerSubPage = function(page) { OptionsPage.registeredPages_[page.name] = page; var pageNav = document.createElement('li'); pageNav.id = page.name + 'PageNav'; pageNav.className = 'navbar-item hidden'; pageNav.setAttribute('pageName', page.name); pageNav.textContent = page.title; var subpagesnav = $('subpagesnav'); subpagesnav.appendChild(pageNav); page.tab = pageNav; page.initializePage(); }; /** * Registers a new Overlay page. * @param {OptionsPage} page Page to register, must be a class derived from * OptionsPage. */ OptionsPage.registerOverlay = function(page) { OptionsPage.registeredOverlayPages_[page.name] = page; page.tab = undefined; page.isOverlay = true; page.initializePage(); }; /** * Callback for window.onpopstate. * @param {Object} data State data pushed into history. */ OptionsPage.setState = function(data) { if (data && data.pageName) { OptionsPage.showPageByName(data.pageName); } }; /** * Initializes the complete options page. This will cause * all C++ handlers to be invoked to do final setup. */ OptionsPage.initialize = function() { chrome.send('coreOptionsInitialize'); }; OptionsPage.prototype = { __proto__: cr.EventTarget.prototype, /** * Initializes page content. */ initializePage: function() {}, /** * Sets managed banner visibility state. */ setManagedBannerVisibility: function(visible) { this.managed = visible; if (this.visible) { $('managed-prefs-banner').style.display = visible ? 'block' : 'none'; } }, /** * Gets page visibility state. */ get visible() { var page = $(this.pageDivName); return page && page.ownerDocument.defaultView.getComputedStyle( page).display == 'block'; }, /** * Sets page visibility. */ set visible(visible) { if ((this.visible && visible) || (!this.visible && !visible)) return; if (visible) { this.pageDiv.style.display = 'block'; if (this.isOverlay) { var overlay = $('overlay'); overlay.classList.remove('hidden'); document.addEventListener('keydown', OptionsPage.clearOverlaysOnEsc_); } else { var banner = $('managed-prefs-banner'); banner.style.display = this.managed ? 'block' : 'none'; // Recent webkit change no longer allows url change from "chrome://". window.history.pushState({pageName: this.name}, this.title); } if (this.tab) { this.tab.classList.add('navbar-item-selected'); if (this.tab.parentNode && this.tab.parentNode.id == 'subpagesnav') this.tab.classList.remove('hidden'); } } else { if (this.isOverlay) { var overlay = $('overlay'); overlay.classList.add('hidden'); document.removeEventListener('keydown', OptionsPage.clearOverlaysOnEsc_); } this.pageDiv.style.display = 'none'; if (this.tab) { this.tab.classList.remove('navbar-item-selected'); if (this.tab.parentNode && this.tab.parentNode.id == 'subpagesnav') this.tab.classList.add('hidden'); } } cr.dispatchPropertyChange(this, 'visible', visible, !visible); }, /** * Handles a hash value in the URL (such as bar in * chrome://options/foo#bar). Called on page load. By default, this shows * an overlay that matches the hash name, but can be overriden by individual * OptionsPage subclasses to get other behavior. * @param {string} hash The hash value. */ handleHash: function(hash) { OptionsPage.showOverlay(hash); }, }; // Export return { OptionsPage: OptionsPage }; });