home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / AvantBrowser / asetup.exe / _data / webkit / chrome.dll / 0 / BINDATA / 607 < prev    next >
Encoding:
Text File  |  2013-04-03  |  11.4 KB  |  344 lines

  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. cr.define('uber', function() {
  6.   /**
  7.    * Options for how web history should be handled.
  8.    */
  9.   var HISTORY_STATE_OPTION = {
  10.     PUSH: 1,    // Push a new history state.
  11.     REPLACE: 2, // Replace the current history state.
  12.     NONE: 3,    // Ignore this history state change.
  13.   };
  14.  
  15.   /**
  16.    * We cache a reference to the #navigation frame here so we don't need to grab
  17.    * it from the DOM on each scroll.
  18.    * @type {Node}
  19.    * @private
  20.    */
  21.   var navFrame;
  22.  
  23.   /**
  24.    * Handles page initialization.
  25.    */
  26.   function onLoad(e) {
  27.     navFrame = $('navigation');
  28.     navFrame.dataset.width = navFrame.offsetWidth;
  29.  
  30.     // Select a page based on the page-URL.
  31.     var params = resolvePageInfo();
  32.     showPage(params.id, HISTORY_STATE_OPTION.NONE, params.path);
  33.  
  34.     window.addEventListener('message', handleWindowMessage);
  35.     window.setTimeout(function() {
  36.       document.documentElement.classList.remove('loading');
  37.     }, 0);
  38.  
  39.     // HACK(dbeam): This makes the assumption that any second part to a path
  40.     // will result in needing background navigation. We shortcut it to avoid
  41.     // flicker on load.
  42.     // HACK(csilv): Search URLs aren't overlays, special case them.
  43.     if (params.id == 'settings' && params.path &&
  44.         params.path.indexOf('search') != 0) {
  45.       backgroundNavigation();
  46.     }
  47.   }
  48.  
  49.   /**
  50.    * Find page information from window.location. If the location doesn't
  51.    * point to one of our pages, return default parameters.
  52.    * @return {Object} An object containing the following parameters:
  53.    *     id - The 'id' of the page.
  54.    *     path - A path into the page, including search and hash. Optional.
  55.    */
  56.   function resolvePageInfo() {
  57.     var params = {};
  58.     var path = window.location.pathname;
  59.     if (path.length > 1) {
  60.       // Split the path into id and the remaining path.
  61.       path = path.slice(1);
  62.       var index = path.indexOf('/');
  63.       if (index != -1) {
  64.         params.id = path.slice(0, index);
  65.         params.path = path.slice(index + 1);
  66.       } else {
  67.         params.id = path;
  68.       }
  69.  
  70.       var container = $(params.id);
  71.       if (container) {
  72.         // The id is valid. Add the hash and search parts of the URL to path.
  73.         params.path = (params.path || '') + window.location.search +
  74.             window.location.hash;
  75.       } else {
  76.         // The target sub-page does not exist, discard the params we generated.
  77.         params.id = undefined;
  78.         params.path = undefined;
  79.       }
  80.     }
  81.     // If we don't have a valid page, get a default.
  82.     if (!params.id)
  83.       params.id = getDefaultIframe().id;
  84.  
  85.     return params;
  86.   }
  87.  
  88.   /**
  89.    * Handler for window.onpopstate.
  90.    * @param {Event} e The history event.
  91.    */
  92.   function onPopHistoryState(e) {
  93.     if (e.state && e.state.pageId)
  94.       showPage(e.state.pageId, HISTORY_STATE_OPTION.NONE);
  95.   }
  96.  
  97.   /**
  98.    * @return {Object} The default iframe container.
  99.    */
  100.   function getDefaultIframe() {
  101.     return $(loadTimeData.getString('helpHost'));
  102.   }
  103.  
  104.   /**
  105.    * @return {Object} The currently selected iframe container.
  106.    */
  107.   function getSelectedIframe() {
  108.     return document.querySelector('.iframe-container.selected');
  109.   }
  110.  
  111.   /**
  112.    * Handles postMessage calls from the iframes of the contained pages.
  113.    *
  114.    * The pages request functionality from this object by passing an object of
  115.    * the following form:
  116.    *
  117.    *  { method : "methodToInvoke",
  118.    *    params : {...}
  119.    *  }
  120.    *
  121.    * |method| is required, while |params| is optional. Extra parameters required
  122.    * by a method must be specified by that method's documentation.
  123.    *
  124.    * @param {Event} e The posted object.
  125.    */
  126.   function handleWindowMessage(e) {
  127.     if (e.data.method === 'beginInterceptingEvents')
  128.       backgroundNavigation();
  129.     else if (e.data.method === 'stopInterceptingEvents')
  130.       foregroundNavigation();
  131.     else if (e.data.method === 'setPath')
  132.       setPath(e.origin, e.data.params.path);
  133.     else if (e.data.method === 'setTitle')
  134.       setTitle(e.origin, e.data.params.title);
  135.     else if (e.data.method === 'showPage')
  136.       showPage(e.data.params.pageId, HISTORY_STATE_OPTION.PUSH);
  137.     else if (e.data.method === 'navigationControlsLoaded')
  138.       onNavigationControlsLoaded();
  139.     else if (e.data.method === 'adjustToScroll')
  140.       adjustToScroll(e.data.params);
  141.     else if (e.data.method === 'mouseWheel')
  142.       forwardMouseWheel(e.data.params);
  143.     else
  144.       console.error('Received unexpected message', e.data);
  145.   }
  146.  
  147.   /**
  148.    * Sends the navigation iframe to the background.
  149.    */
  150.   function backgroundNavigation() {
  151.     navFrame.classList.add('background');
  152.     navFrame.firstChild.tabIndex = -1;
  153.     navFrame.firstChild.setAttribute('aria-hidden', true);
  154.   }
  155.  
  156.   /**
  157.    * Retrieves the navigation iframe from the background.
  158.    */
  159.   function foregroundNavigation() {
  160.     navFrame.classList.remove('background');
  161.     navFrame.firstChild.tabIndex = 0;
  162.     navFrame.firstChild.removeAttribute('aria-hidden');
  163.   }
  164.  
  165.   /**
  166.    * Enables or disables animated transitions when changing content while
  167.    * horizontally scrolled.
  168.    * @param {boolean} enabled True if enabled, else false to disable.
  169.    */
  170.   function setContentChanging(enabled) {
  171.     navFrame.classList[enabled ? 'add' : 'remove']('changing-content');
  172.  
  173.     if (isRTL()) {
  174.       uber.invokeMethodOnWindow(navFrame.firstChild.contentWindow,
  175.                                 'setContentChanging',
  176.                                 enabled);
  177.     }
  178.   }
  179.  
  180.   /**
  181.    * Get an iframe based on the origin of a received post message.
  182.    * @param {string} origin The origin of a post message.
  183.    * @return {!HTMLElement} The frame associated to |origin| or null.
  184.    */
  185.   function getIframeFromOrigin(origin) {
  186.     assert(origin.substr(-1) != '/', 'invalid origin given');
  187.     var query = '.iframe-container > iframe[src^="' + origin + '/"]';
  188.     return document.querySelector(query);
  189.   }
  190.  
  191.   /**
  192.    * Changes the path past the page title (i.e. chrome://chrome/settings/(.*)).
  193.    * @param {string} path The new /path/ to be set after the page name.
  194.    * @param {number} historyOption The type of history modification to make.
  195.    */
  196.   function changePathTo(path, historyOption) {
  197.     assert(!path || path.substr(-1) != '/', 'invalid path given');
  198.  
  199.     var histFunc;
  200.     if (historyOption == HISTORY_STATE_OPTION.PUSH)
  201.       histFunc = window.history.pushState;
  202.     else if (historyOption == HISTORY_STATE_OPTION.REPLACE)
  203.       histFunc = window.history.replaceState;
  204.  
  205.     assert(histFunc, 'invalid historyOption given ' + historyOption);
  206.  
  207.     var pageId = getSelectedIframe().id;
  208.     var args = [{pageId: pageId}, '', '/' + pageId + '/' + (path || '')];
  209.     histFunc.apply(window.history, args);
  210.   }
  211.  
  212.   /**
  213.    * Sets the "path" of the page (actually the path after the first '/' char).
  214.    * @param {Object} origin The origin of the source iframe.
  215.    * @param {string} title The new "path".
  216.    */
  217.   function setPath(origin, path) {
  218.     assert(!path || path[0] != '/', 'invalid path sent from ' + origin);
  219.     // Only update the currently displayed path if this is the visible frame.
  220.     if (getIframeFromOrigin(origin).parentNode == getSelectedIframe())
  221.       changePathTo(path, HISTORY_STATE_OPTION.REPLACE);
  222.   }
  223.  
  224.   /**
  225.    * Sets the title of the page.
  226.    * @param {Object} origin The origin of the source iframe.
  227.    * @param {string} title The title of the page.
  228.    */
  229.   function setTitle(origin, title) {
  230.     // Cache the title for the client iframe, i.e., the iframe setting the
  231.     // title. querySelector returns the actual iframe element, so use parentNode
  232.     // to get back to the container.
  233.     var container = getIframeFromOrigin(origin).parentNode;
  234.     container.dataset.title = title;
  235.  
  236.     // Only update the currently displayed title if this is the visible frame.
  237.     if (container == getSelectedIframe())
  238.       document.title = title;
  239.   }
  240.  
  241.   /**
  242.    * Selects a subpage. This is called from uber-frame.
  243.    * @param {String} pageId Should matche an id of one of the iframe containers.
  244.    * @param {integer} historyOption Indicates whether we should push or replace
  245.    *     browser history.
  246.    * @param {String} path A sub-page path.
  247.    */
  248.   function showPage(pageId, historyOption, path) {
  249.     var container = $(pageId);
  250.     var lastSelected = document.querySelector('.iframe-container.selected');
  251.  
  252.     // Lazy load of iframe contents.
  253.     var sourceUrl = container.dataset.url + (path || '');
  254.     var frame = container.querySelector('iframe');
  255.     if (!frame) {
  256.       frame = container.ownerDocument.createElement('iframe');
  257.       container.appendChild(frame);
  258.       frame.src = sourceUrl;
  259.     } else {
  260.       // There's no particularly good way to know what the current URL of the
  261.       // content frame is as we don't have access to its contentWindow's
  262.       // location, so just replace every time until necessary to do otherwise.
  263.       frame.contentWindow.location.replace(sourceUrl);
  264.     }
  265.  
  266.     // If the last selected container is already showing, ignore the rest.
  267.     if (lastSelected === container)
  268.       return;
  269.  
  270.     if (lastSelected)
  271.       lastSelected.classList.remove('selected');
  272.     container.classList.add('selected');
  273.  
  274.     setContentChanging(true);
  275.     adjustToScroll(0);
  276.  
  277.     var selectedFrame = getSelectedIframe().querySelector('iframe');
  278.     uber.invokeMethodOnWindow(selectedFrame.contentWindow, 'frameSelected');
  279.  
  280.     if (historyOption != HISTORY_STATE_OPTION.NONE)
  281.       changePathTo(path, historyOption);
  282.  
  283.     if (container.dataset.title)
  284.       document.title = container.dataset.title;
  285.     $('favicon').href = 'chrome://theme/' + container.dataset.favicon;
  286.     $('favicon2x').href = 'chrome://theme/' + container.dataset.favicon + '@2x';
  287.  
  288.     updateNavigationControls();
  289.   }
  290.  
  291.   function onNavigationControlsLoaded() {
  292.     updateNavigationControls();
  293.   }
  294.  
  295.   /**
  296.    * Sends a message to uber-frame to update the appearance of the nav controls.
  297.    * It should be called whenever the selected iframe changes.
  298.    */
  299.   function updateNavigationControls() {
  300.     var iframe = getSelectedIframe();
  301.     uber.invokeMethodOnWindow(navFrame.firstChild.contentWindow,
  302.                               'changeSelection', {pageId: iframe.id});
  303.   }
  304.  
  305.   /**
  306.    * Forwarded scroll offset from a content frame's scroll handler.
  307.    * @param {number} scrollOffset The scroll offset from the content frame.
  308.    */
  309.   function adjustToScroll(scrollOffset) {
  310.     // NOTE: The scroll is reset to 0 and easing turned on every time a user
  311.     // switches frames. If we receive a non-zero value it has to have come from
  312.     // a real user scroll, so we disable easing when this happens.
  313.     if (scrollOffset != 0)
  314.       setContentChanging(false);
  315.  
  316.     if (isRTL()) {
  317.       uber.invokeMethodOnWindow(navFrame.firstChild.contentWindow,
  318.                                 'adjustToScroll',
  319.                                 scrollOffset);
  320.       var navWidth = Math.max(0, +navFrame.dataset.width + scrollOffset);
  321.       navFrame.style.width = navWidth + 'px';
  322.     } else {
  323.       navFrame.style.webkitTransform = 'translateX(' + -scrollOffset + 'px)';
  324.     }
  325.   }
  326.  
  327.   /**
  328.    * Forward scroll wheel events to subpages.
  329.    * @param {Object} params Relevant parameters of wheel event.
  330.    */
  331.   function forwardMouseWheel(params) {
  332.     var iframe = getSelectedIframe().querySelector('iframe');
  333.     uber.invokeMethodOnWindow(iframe.contentWindow, 'mouseWheel', params);
  334.   }
  335.  
  336.   return {
  337.     onLoad: onLoad,
  338.     onPopHistoryState: onPopHistoryState
  339.   };
  340. });
  341.  
  342. window.addEventListener('popstate', uber.onPopHistoryState);
  343. document.addEventListener('DOMContentLoaded', uber.onLoad);
  344.