home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / AvantBrowser / asetup.exe / _data / webkit / chrome.dll / 0 / BINDATA / 609 < prev    next >
Encoding:
Text File  |  2013-04-03  |  15.5 KB  |  507 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. // 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. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  11. // Use of this source code is governed by a BSD-style license that can be
  12. // found in the LICENSE file.
  13.  
  14. /**
  15.  * The global object.
  16.  * @type {!Object}
  17.  * @const
  18.  */
  19. var global = this;
  20.  
  21. /**
  22.  * Alias for document.getElementById.
  23.  * @param {string} id The ID of the element to find.
  24.  * @return {HTMLElement} The found element or null if not found.
  25.  */
  26. function $(id) {
  27.   return document.getElementById(id);
  28. }
  29.  
  30. /**
  31.  * Calls chrome.send with a callback and restores the original afterwards.
  32.  * @param {string} name The name of the message to send.
  33.  * @param {!Array} params The parameters to send.
  34.  * @param {string} callbackName The name of the function that the backend calls.
  35.  * @param {!Function} callback The function to call.
  36.  */
  37. function chromeSend(name, params, callbackName, callback) {
  38.   var old = global[callbackName];
  39.   global[callbackName] = function() {
  40.     // restore
  41.     global[callbackName] = old;
  42.  
  43.     var args = Array.prototype.slice.call(arguments);
  44.     return callback.apply(global, args);
  45.   };
  46.   chrome.send(name, params);
  47. }
  48.  
  49. /**
  50.  * Generates a CSS url string.
  51.  * @param {string} s The URL to generate the CSS url for.
  52.  * @return {string} The CSS url string.
  53.  */
  54. function url(s) {
  55.   // http://www.w3.org/TR/css3-values/#uris
  56.   // Parentheses, commas, whitespace characters, single quotes (') and double
  57.   // quotes (") appearing in a URI must be escaped with a backslash
  58.   var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1');
  59.   // WebKit has a bug when it comes to URLs that end with \
  60.   // https://bugs.webkit.org/show_bug.cgi?id=28885
  61.   if (/\\\\$/.test(s2)) {
  62.     // Add a space to work around the WebKit bug.
  63.     s2 += ' ';
  64.   }
  65.   return 'url("' + s2 + '")';
  66. }
  67.  
  68. /**
  69.  * Parses query parameters from Location.
  70.  * @param {string} location The URL to generate the CSS url for.
  71.  * @return {object} Dictionary containing name value pairs for URL
  72.  */
  73. function parseQueryParams(location) {
  74.   var params = {};
  75.   var query = unescape(location.search.substring(1));
  76.   var vars = query.split('&');
  77.   for (var i = 0; i < vars.length; i++) {
  78.     var pair = vars[i].split('=');
  79.     params[pair[0]] = pair[1];
  80.   }
  81.   return params;
  82. }
  83.  
  84. function findAncestorByClass(el, className) {
  85.   return findAncestor(el, function(el) {
  86.     if (el.classList)
  87.       return el.classList.contains(className);
  88.     return null;
  89.   });
  90. }
  91.  
  92. /**
  93.  * Return the first ancestor for which the {@code predicate} returns true.
  94.  * @param {Node} node The node to check.
  95.  * @param {function(Node) : boolean} predicate The function that tests the
  96.  *     nodes.
  97.  * @return {Node} The found ancestor or null if not found.
  98.  */
  99. function findAncestor(node, predicate) {
  100.   var last = false;
  101.   while (node != null && !(last = predicate(node))) {
  102.     node = node.parentNode;
  103.   }
  104.   return last ? node : null;
  105. }
  106.  
  107. function swapDomNodes(a, b) {
  108.   var afterA = a.nextSibling;
  109.   if (afterA == b) {
  110.     swapDomNodes(b, a);
  111.     return;
  112.   }
  113.   var aParent = a.parentNode;
  114.   b.parentNode.replaceChild(a, b);
  115.   aParent.insertBefore(b, afterA);
  116. }
  117.  
  118. /**
  119.  * Disables text selection and dragging, with optional whitelist callbacks.
  120.  * @param {function(Event):boolean=} opt_allowSelectStart Unless this function
  121.  *    is defined and returns true, the onselectionstart event will be
  122.  *    surpressed.
  123.  * @param {function(Event):boolean=} opt_allowDragStart Unless this function
  124.  *    is defined and returns true, the ondragstart event will be surpressed.
  125.  */
  126. function disableTextSelectAndDrag(opt_allowSelectStart, opt_allowDragStart) {
  127.   // Disable text selection.
  128.   document.onselectstart = function(e) {
  129.     if (!(opt_allowSelectStart && opt_allowSelectStart.call(this, e)))
  130.       e.preventDefault();
  131.   };
  132.  
  133.   // Disable dragging.
  134.   document.ondragstart = function(e) {
  135.     if (!(opt_allowDragStart && opt_allowDragStart.call(this, e)))
  136.       e.preventDefault();
  137.   };
  138. }
  139.  
  140. /**
  141.  * Call this to stop clicks on <a href="#"> links from scrolling to the top of
  142.  * the page (and possibly showing a # in the link).
  143.  */
  144. function preventDefaultOnPoundLinkClicks() {
  145.   document.addEventListener('click', function(e) {
  146.     var anchor = findAncestor(e.target, function(el) {
  147.       return el.tagName == 'A';
  148.     });
  149.     // Use getAttribute() to prevent URL normalization.
  150.     if (anchor && anchor.getAttribute('href') == '#')
  151.       e.preventDefault();
  152.   });
  153. }
  154.  
  155. /**
  156.  * Check the directionality of the page.
  157.  * @return {boolean} True if Chrome is running an RTL UI.
  158.  */
  159. function isRTL() {
  160.   return document.documentElement.dir == 'rtl';
  161. }
  162.  
  163. /**
  164.  * Simple common assertion API
  165.  * @param {*} condition The condition to test.  Note that this may be used to
  166.  *     test whether a value is defined or not, and we don't want to force a
  167.  *     cast to Boolean.
  168.  * @param {string=} opt_message A message to use in any error.
  169.  */
  170. function assert(condition, opt_message) {
  171.   'use strict';
  172.   if (!condition) {
  173.     var msg = 'Assertion failed';
  174.     if (opt_message)
  175.       msg = msg + ': ' + opt_message;
  176.     throw new Error(msg);
  177.   }
  178. }
  179.  
  180. /**
  181.  * Get an element that's known to exist by its ID. We use this instead of just
  182.  * calling getElementById and not checking the result because this lets us
  183.  * satisfy the JSCompiler type system.
  184.  * @param {string} id The identifier name.
  185.  * @return {!Element} the Element.
  186.  */
  187. function getRequiredElement(id) {
  188.   var element = $(id);
  189.   assert(element, 'Missing required element: ' + id);
  190.   return element;
  191. }
  192.  
  193. // Handle click on a link. If the link points to a chrome: or file: url, then
  194. // call into the browser to do the navigation.
  195. document.addEventListener('click', function(e) {
  196.   // Allow preventDefault to work.
  197.   if (!e.returnValue)
  198.     return;
  199.  
  200.   var el = e.target;
  201.   if (el.nodeType == Node.ELEMENT_NODE &&
  202.       el.webkitMatchesSelector('A, A *')) {
  203.     while (el.tagName != 'A') {
  204.       el = el.parentElement;
  205.     }
  206.  
  207.     if ((el.protocol == 'file:' || el.protocol == 'about:') &&
  208.         (e.button == 0 || e.button == 1)) {
  209.       chrome.send('navigateToUrl', [
  210.         el.href,
  211.         el.target,
  212.         e.button,
  213.         e.altKey,
  214.         e.ctrlKey,
  215.         e.metaKey,
  216.         e.shiftKey
  217.       ]);
  218.       e.preventDefault();
  219.     }
  220.   }
  221. });
  222.  
  223. /**
  224.  * Creates a new URL which is the old URL with a GET param of key=value.
  225.  * @param {string} url The base URL. There is not sanity checking on the URL so
  226.  *     it must be passed in a proper format.
  227.  * @param {string} key The key of the param.
  228.  * @param {string} value The value of the param.
  229.  * @return {string} The new URL.
  230.  */
  231. function appendParam(url, key, value) {
  232.   var param = encodeURIComponent(key) + '=' + encodeURIComponent(value);
  233.  
  234.   if (url.indexOf('?') == -1)
  235.     return url + '?' + param;
  236.   return url + '&' + param;
  237. }
  238.  
  239. /**
  240.  * Creates a new URL for a favicon request.
  241.  * @param {string} url The url for the favicon.
  242.  * @param {number=} opt_size Optional preferred size of the favicon.
  243.  * @return {string} Updated URL for the favicon.
  244.  */
  245. function getFaviconURL(url, opt_size) {
  246.   var size = opt_size || 16;
  247.   return 'chrome://favicon/size/' + size + '@' +
  248.       window.devicePixelRatio + 'x/' + url;
  249. }
  250.  
  251. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  252. // Use of this source code is governed by a BSD-style license that can be
  253. // found in the LICENSE file.
  254.  
  255. /**
  256.  * @fileoverview A collection of utility methods for UberPage and its contained
  257.  *     pages.
  258.  */
  259.  
  260. cr.define('uber', function() {
  261.  
  262.   /**
  263.    * Fixed position header elements on the page to be shifted by handleScroll.
  264.    * @type {NodeList}
  265.    */
  266.   var headerElements;
  267.  
  268.   /**
  269.    * This should be called by uber content pages when DOM content has loaded.
  270.    */
  271.   function onContentFrameLoaded() {
  272.     headerElements = document.getElementsByTagName('header');
  273.     document.addEventListener('scroll', handleScroll);
  274.  
  275.     // Trigger the scroll handler to tell the navigation if our page started
  276.     // with some scroll (happens when you use tab restore).
  277.     handleScroll();
  278.  
  279.     window.addEventListener('message', handleWindowMessage);
  280.   }
  281.  
  282.   /**
  283.    * Handles scroll events on the document. This adjusts the position of all
  284.    * headers and updates the parent frame when the page is scrolled.
  285.    * @private
  286.    */
  287.   function handleScroll() {
  288.     var offset = document.body.scrollLeft * -1;
  289.     for (var i = 0; i < headerElements.length; i++)
  290.       headerElements[i].style.webkitTransform = 'translateX(' + offset + 'px)';
  291.  
  292.     invokeMethodOnParent('adjustToScroll', document.body.scrollLeft);
  293.   };
  294.  
  295.   /**
  296.    * Handles 'message' events on window.
  297.    * @param {Event} e The message event.
  298.    */
  299.   function handleWindowMessage(e) {
  300.     if (e.data.method === 'frameSelected')
  301.       handleFrameSelected();
  302.     else if (e.data.method === 'mouseWheel')
  303.       handleMouseWheel(e.data.params);
  304.   }
  305.  
  306.   /**
  307.    * This is called when a user selects this frame via the navigation bar
  308.    * frame (and is triggered via postMessage() from the uber page).
  309.    * @private
  310.    */
  311.   function handleFrameSelected() {
  312.     document.body.scrollLeft = 0;
  313.   }
  314.  
  315.   /**
  316.    * Called when a user mouse wheels (or trackpad scrolls) over the nav frame.
  317.    * The wheel event is forwarded here and we scroll the body.
  318.    * There's no way to figure out the actual scroll amount for a given delta.
  319.    * It differs for every platform and even initWebKitWheelEvent takes a
  320.    * pixel amount instead of a wheel delta. So we just choose something
  321.    * reasonable and hope no one notices the difference.
  322.    * @param {Object} params A structure that holds wheel deltas in X and Y.
  323.    */
  324.   function handleMouseWheel(params) {
  325.     document.body.scrollTop -= params.deltaY * 49 / 120;
  326.     document.body.scrollLeft -= params.deltaX * 49 / 120;
  327.   }
  328.  
  329.   /**
  330.    * Invokes a method on the parent window (UberPage). This is a convenience
  331.    * method for API calls into the uber page.
  332.    * @param {String} method The name of the method to invoke.
  333.    * @param {Object=} opt_params Optional property bag of parameters to pass to
  334.    *     the invoked method.
  335.    * @private
  336.    */
  337.   function invokeMethodOnParent(method, opt_params) {
  338.     if (window.location == window.parent.location)
  339.       return;
  340.  
  341.     invokeMethodOnWindow(window.parent, method, opt_params, 'chrome://chrome');
  342.   }
  343.  
  344.   /**
  345.    * Invokes a method on the target window.
  346.    * @param {String} method The name of the method to invoke.
  347.    * @param {Object=} opt_params Optional property bag of parameters to pass to
  348.    *     the invoked method.
  349.    * @param {String=} opt_url The origin of the target window.
  350.    * @private
  351.    */
  352.   function invokeMethodOnWindow(targetWindow, method, opt_params, opt_url) {
  353.     var data = {method: method, params: opt_params};
  354.     targetWindow.postMessage(data, opt_url ? opt_url : '*');
  355.   }
  356.  
  357.   return {
  358.     invokeMethodOnParent: invokeMethodOnParent,
  359.     invokeMethodOnWindow: invokeMethodOnWindow,
  360.     onContentFrameLoaded: onContentFrameLoaded,
  361.   };
  362. });
  363.  
  364.  
  365. cr.define('uber_frame', function() {
  366.  
  367.   /**
  368.    * Handles page initialization.
  369.    */
  370.   function onLoad() {
  371.     var navigationItems = document.querySelectorAll('li');
  372.  
  373.     for (var i = 0; i < navigationItems.length; ++i) {
  374.       navigationItems[i].addEventListener('click', onNavItemClicked);
  375.     }
  376.  
  377.     window.addEventListener('message', handleWindowMessage);
  378.     uber.invokeMethodOnParent('navigationControlsLoaded');
  379.  
  380.     document.documentElement.addEventListener('mousewheel', onMouseWheel);
  381.   }
  382.  
  383.   /**
  384.    * Handles clicks on the navigation controls (switches the page and updates
  385.    * the URL).
  386.    * @param {Event} e The click event.
  387.    */
  388.   function onNavItemClicked(e) {
  389.     // Though pointer-event: none; is applied to the .selected nav item, users
  390.     // can still tab to them and press enter/space which simulates a click.
  391.     if (e.target.classList.contains('selected'))
  392.       return;
  393.  
  394.     // Extensions can override Uber content (e.g., if the user has a history
  395.     // extension, it should display when the 'History' navigation is clicked).
  396.     if (e.currentTarget.getAttribute('override') == 'yes') {
  397.       window.open('chrome://' + e.currentTarget.getAttribute('controls'),
  398.           '_blank');
  399.       return;
  400.     }
  401.  
  402.     uber.invokeMethodOnParent('showPage',
  403.        {pageId: e.currentTarget.getAttribute('controls')});
  404.  
  405.     setSelection(e.currentTarget);
  406.   }
  407.  
  408.   /**
  409.    * Handles postMessage from chrome://chrome.
  410.    * @param {Event} e The post data.
  411.    */
  412.   function handleWindowMessage(e) {
  413.     if (e.data.method === 'changeSelection')
  414.       changeSelection(e.data.params);
  415.     else if (e.data.method === 'adjustToScroll')
  416.       adjustToScroll(e.data.params);
  417.     else if (e.data.method === 'setContentChanging')
  418.       setContentChanging(e.data.params);
  419.     else
  420.       console.error('Received unexpected message', e.data);
  421.   }
  422.  
  423.   /**
  424.    * Changes the selected nav control.
  425.    * @param {Object} params Must contain pageId.
  426.    */
  427.   function changeSelection(params) {
  428.     var navItem =
  429.         document.querySelector('li[controls="' + params.pageId + '"]');
  430.     setSelection(navItem);
  431.   }
  432.  
  433.   /**
  434.    * Sets selection on the given nav item.
  435.    * @param {Boolean} newSelection The item to be selected.
  436.    */
  437.   function setSelection(newSelection) {
  438.     var lastSelectedNavItem = document.querySelector('li.selected');
  439.     if (lastSelectedNavItem !== newSelection) {
  440.       newSelection.classList.add('selected');
  441.       if (lastSelectedNavItem)
  442.         lastSelectedNavItem.classList.remove('selected');
  443.     }
  444.   }
  445.  
  446.   /**
  447.    * Adjusts this frame's content to scrolls from the outer frame. This is done
  448.    * to obscure text in RTL as a user scrolls over the content of this frame (as
  449.    * currently RTL scrollbars still draw on the right).
  450.    * @param {number} scroll document.body.scrollLeft of the content frame.
  451.    */
  452.   function adjustToScroll(scrollLeft) {
  453.     assert(isRTL());
  454.     document.body.style.webkitTransform = 'translateX(' + -scrollLeft + 'px)';
  455.   }
  456.  
  457.   /**
  458.    * Enable/disable an animation to ease the nav bar back into view when
  459.    * changing content while horizontally scrolled.
  460.    * @param {boolean} enabled Whether easing should be enabled.
  461.    */
  462.   function setContentChanging(enabled) {
  463.     assert(isRTL());
  464.     document.documentElement.classList[enabled ? 'add' : 'remove'](
  465.         'changing-content');
  466.   }
  467.  
  468.   /**
  469.    * Handles mouse wheels on the top level element. Forwards them to uber.js.
  470.    * @param {Event} e The mouse wheel event.
  471.    */
  472.   function onMouseWheel(e) {
  473.     uber.invokeMethodOnParent('mouseWheel',
  474.         {deltaX: e.wheelDeltaX, deltaY: e.wheelDeltaY});
  475.   }
  476.  
  477.   /**
  478.    * @return {Object} The currently selected iframe container.
  479.    * @private
  480.    */
  481.   function getSelectedIframe() {
  482.     return document.querySelector('.iframe-container.selected');
  483.   }
  484.  
  485.   /**
  486.    * Finds the <li> element whose 'controls' attribute is |controls| and sets
  487.    * its 'override' attribute to |override|.
  488.    * @param {string} controls The value of the 'controls' attribute of the
  489.    *     element to change.
  490.    * @param {string} override The value to set for the 'override' attribute of
  491.    *     that element (either 'yes' or 'no').
  492.    */
  493.   function setNavigationOverride(controls, override) {
  494.     var navItem =
  495.         document.querySelector('li[controls="' + controls + '"]');
  496.     navItem.setAttribute('override', override);
  497.   }
  498.  
  499.   return {
  500.     onLoad: onLoad,
  501.     setNavigationOverride: setNavigationOverride,
  502.   };
  503.  
  504. });
  505.  
  506. document.addEventListener('DOMContentLoaded', uber_frame.onLoad);
  507.