Commit fc8d745a authored by vitalyp@chromium.org's avatar vitalyp@chromium.org

Typecheck JS files for chrome://history

BUG=393873
R=dbeam@chromium.org
TEST=./third_party/closure_compiler/runner/build_runner_jar.py && gyp --depth . chrome/browser/resources/history/compiled_resources.gyp && ninja -C out/Default

Review URL: https://codereview.chromium.org/454223004

Cr-Commit-Position: refs/heads/master@{#291243}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291243 0039d316-1c4b-4281-b951-d872f2087c98
parent ac97fa75
# Copyright 2014 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.
{
'targets': [
{
'target_name': 'history',
'variables': {
'depends': [
'../../../../ui/webui/resources/js/assert.js',
'../../../../ui/webui/resources/js/cr.js',
'../../../../ui/webui/resources/js/cr/ui.js',
'../../../../ui/webui/resources/js/cr/ui/alert_overlay.js',
'../../../../ui/webui/resources/js/cr/ui/command.js',
'../../../../ui/webui/resources/js/cr/ui/focus_grid.js',
'../../../../ui/webui/resources/js/cr/ui/focus_manager.js',
'../../../../ui/webui/resources/js/cr/ui/focus_row.js',
'../../../../ui/webui/resources/js/cr/ui/menu.js',
'../../../../ui/webui/resources/js/cr/ui/menu_button.js',
'../../../../ui/webui/resources/js/cr/ui/menu_item.js',
'../../../../ui/webui/resources/js/cr/ui/overlay.js',
'../../../../ui/webui/resources/js/cr/ui/position_util.js',
'../../../../ui/webui/resources/js/event_tracker.js',
'../../../../ui/webui/resources/js/load_time_data.js',
'../../../../ui/webui/resources/js/util.js',
'history_focus_manager.js',
],
'externs': ['<(CLOSURE_DIR)/externs/chrome_send_externs.js'],
},
'includes': ['../../../../third_party/closure_compiler/compile_js.gypi'],
}
],
}
This diff is collapsed.
...@@ -9,6 +9,7 @@ var FocusManager = cr.ui.FocusManager; ...@@ -9,6 +9,7 @@ var FocusManager = cr.ui.FocusManager;
* "background" pages (i.e., those in a dialog that is not the topmost overlay) * "background" pages (i.e., those in a dialog that is not the topmost overlay)
* do not receive focus. * do not receive focus.
* @constructor * @constructor
* @extends {cr.ui.FocusManager}
*/ */
function HistoryFocusManager() { function HistoryFocusManager() {
} }
......
...@@ -327,6 +327,10 @@ scoped_ptr<base::DictionaryValue> BrowsingHistoryHandler::HistoryEntry::ToValue( ...@@ -327,6 +327,10 @@ scoped_ptr<base::DictionaryValue> BrowsingHistoryHandler::HistoryEntry::ToValue(
if (domain.empty()) if (domain.empty())
domain = base::UTF8ToUTF16(url.scheme() + ":"); domain = base::UTF8ToUTF16(url.scheme() + ":");
// The items which are to be written into result are also described in
// chrome/browser/resources/history/history.js in @typedef for
// HistoryEntry. Please update it whenever you add or remove
// any keys in result.
result->SetString("domain", domain); result->SetString("domain", domain);
result->SetDouble("time", time.ToJsTime()); result->SetDouble("time", time.ToJsTime());
...@@ -783,6 +787,10 @@ void BrowsingHistoryHandler::QueryComplete( ...@@ -783,6 +787,10 @@ void BrowsingHistoryHandler::QueryComplete(
accept_languages)); accept_languages));
} }
// The items which are to be written into results_info_value_ are also
// described in chrome/browser/resources/history/history.js in @typedef for
// HistoryQuery. Please update it whenever you add or remove any keys in
// results_info_value_.
results_info_value_.SetString("term", search_text); results_info_value_.SetString("term", search_text);
results_info_value_.SetBoolean("finished", results->reached_beginning()); results_info_value_.SetBoolean("finished", results->reached_beginning());
......
...@@ -301,6 +301,7 @@ var cr = function() { ...@@ -301,6 +301,7 @@ var cr = function() {
defineProperty: defineProperty, defineProperty: defineProperty,
dispatchPropertyChange: dispatchPropertyChange, dispatchPropertyChange: dispatchPropertyChange,
dispatchSimpleEvent: dispatchSimpleEvent, dispatchSimpleEvent: dispatchSimpleEvent,
exportPath: exportPath,
getUid: getUid, getUid: getUid,
PropertyKind: PropertyKind, PropertyKind: PropertyKind,
......
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
cr.define('alertOverlay', function() { cr.define('alertOverlay', function() {
/** /**
* The confirm <button>. * The confirm <button>.
* @type {HTMLButtonElement} * @type {HTMLElement}
*/ */
var okButton; var okButton;
/** /**
* The cancel <button>. * The cancel <button>.
* @type {HTMLButtonElement} * @type {HTMLElement}
*/ */
var cancelButton; var cancelButton;
...@@ -46,13 +46,14 @@ cr.define('alertOverlay', function() { ...@@ -46,13 +46,14 @@ cr.define('alertOverlay', function() {
* no button is shown. * no button is shown.
* @param {string=} cancelTitle The title of the cancel button. If undefined * @param {string=} cancelTitle The title of the cancel button. If undefined
* or empty, no button is shown. * or empty, no button is shown.
* @param {function=} okCallback A function to be called when the user presses * @param {function()=} opt_okCallback A function to be called when the user
* the ok button. Can be undefined if |okTitle| is falsey. * presses the ok button. Can be undefined if |okTitle| is falsey.
* @param {function=} cancelCallback A function to be called when the user * @param {function()=} opt_cancelCallback A function to be called when the
* presses the cancel button. Can be undefined if |cancelTitle| is falsey. * user presses the cancel button. Can be undefined if |cancelTitle| is
* falsey.
*/ */
function setValues( function setValues(title, message, okTitle, cancelTitle, opt_okCallback,
title, message, okTitle, cancelTitle, okCallback, cancelCallback) { opt_cancelCallback) {
if (typeof title != 'undefined') if (typeof title != 'undefined')
$('alertOverlayTitle').textContent = title; $('alertOverlayTitle').textContent = title;
$('alertOverlayTitle').hidden = typeof title == 'undefined'; $('alertOverlayTitle').hidden = typeof title == 'undefined';
...@@ -64,12 +65,12 @@ cr.define('alertOverlay', function() { ...@@ -64,12 +65,12 @@ cr.define('alertOverlay', function() {
if (okTitle) if (okTitle)
okButton.textContent = okTitle; okButton.textContent = okTitle;
okButton.hidden = !okTitle; okButton.hidden = !okTitle;
okButton.clickCallback = okCallback; okButton.clickCallback = opt_okCallback;
if (cancelTitle) if (cancelTitle)
cancelButton.textContent = cancelTitle; cancelButton.textContent = cancelTitle;
cancelButton.hidden = !cancelTitle; cancelButton.hidden = !cancelTitle;
cancelButton.clickCallback = cancelCallback; cancelButton.clickCallback = opt_cancelCallback;
}; };
// Export // Export
......
...@@ -78,7 +78,7 @@ cr.define('cr.ui', function() { ...@@ -78,7 +78,7 @@ cr.define('cr.ui', function() {
* Initializes the command. * Initializes the command.
*/ */
decorate: function() { decorate: function() {
CommandManager.init(this.ownerDocument); CommandManager.init(assert(this.ownerDocument));
if (this.hasAttribute('shortcut')) if (this.hasAttribute('shortcut'))
this.shortcut = this.getAttribute('shortcut'); this.shortcut = this.getAttribute('shortcut');
...@@ -163,25 +163,21 @@ cr.define('cr.ui', function() { ...@@ -163,25 +163,21 @@ cr.define('cr.ui', function() {
/** /**
* The label of the command. * The label of the command.
* @type {string}
*/ */
cr.defineProperty(Command, 'label', cr.PropertyKind.ATTR); cr.defineProperty(Command, 'label', cr.PropertyKind.ATTR);
/** /**
* Whether the command is disabled or not. * Whether the command is disabled or not.
* @type {boolean}
*/ */
cr.defineProperty(Command, 'disabled', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(Command, 'disabled', cr.PropertyKind.BOOL_ATTR);
/** /**
* Whether the command is hidden or not. * Whether the command is hidden or not.
* @type {boolean}
*/ */
cr.defineProperty(Command, 'hidden', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(Command, 'hidden', cr.PropertyKind.BOOL_ATTR);
/** /**
* Whether the command is checked or not. * Whether the command is checked or not.
* @type {boolean}
*/ */
cr.defineProperty(Command, 'checked', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(Command, 'checked', cr.PropertyKind.BOOL_ATTR);
...@@ -191,18 +187,16 @@ cr.define('cr.ui', function() { ...@@ -191,18 +187,16 @@ cr.define('cr.ui', function() {
* If false, the keyboard shortcut text (eg. "Ctrl+X" for the cut command) * If false, the keyboard shortcut text (eg. "Ctrl+X" for the cut command)
* is displayed in menu when the command is assosiated with a menu item. * is displayed in menu when the command is assosiated with a menu item.
* Otherwise, no text is displayed. * Otherwise, no text is displayed.
*
* @type {boolean}
*/ */
cr.defineProperty(Command, 'hideShortcutText', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(Command, 'hideShortcutText', cr.PropertyKind.BOOL_ATTR);
/** /**
* Dispatches a canExecute event on the target. * Dispatches a canExecute event on the target.
* @param {cr.ui.Command} command The command that we are testing for. * @param {!cr.ui.Command} command The command that we are testing for.
* @param {Element} target The target element to dispatch the event on. * @param {EventTarget} target The target element to dispatch the event on.
*/ */
function dispatchCanExecuteEvent(command, target) { function dispatchCanExecuteEvent(command, target) {
var e = new CanExecuteEvent(command, true); var e = new CanExecuteEvent(command);
target.dispatchEvent(e); target.dispatchEvent(e);
command.disabled = !e.canExecute; command.disabled = !e.canExecute;
} }
......
...@@ -41,10 +41,10 @@ cr.define('cr.ui', function() { ...@@ -41,10 +41,10 @@ cr.define('cr.ui', function() {
/** @type {!Node} */ /** @type {!Node} */
this.boundary_ = opt_boundary || document; this.boundary_ = opt_boundary || document;
/** @private {FocusRow.Delegate|undefined} */ /** @private {cr.ui.FocusRow.Delegate|undefined} */
this.delegate_ = opt_delegate; this.delegate_ = opt_delegate;
/** @private {FocusRow.Observer|undefined} */ /** @private {cr.ui.FocusRow.Observer|undefined} */
this.observer_ = opt_observer; this.observer_ = opt_observer;
/** @private {!EventTracker} */ /** @private {!EventTracker} */
......
...@@ -86,17 +86,17 @@ cr.define('cr.ui', function() { ...@@ -86,17 +86,17 @@ cr.define('cr.ui', function() {
}, },
/** /**
* Walks up the ancestors of |el| until a menu item belonging to this menu * Walks up the ancestors of |node| until a menu item belonging to this menu
* is found. * is found.
* @param {Element} el The element to start searching from. * @param {Node} node The node to start searching from.
* @return {cr.ui.MenuItem} The found menu item or null. * @return {cr.ui.MenuItem} The found menu item or null.
* @private * @private
*/ */
findMenuItem_: function(el) { findMenuItem_: function(node) {
while (el && el.parentNode != this) { while (node && node.parentNode != this) {
el = el.parentNode; node = node.parentNode;
} }
return el ? assertInstanceof(el, MenuItem) : null; return node ? assertInstanceof(node, MenuItem) : null;
}, },
/** /**
...@@ -105,7 +105,7 @@ cr.define('cr.ui', function() { ...@@ -105,7 +105,7 @@ cr.define('cr.ui', function() {
* @private * @private
*/ */
handleMouseOver_: function(e) { handleMouseOver_: function(e) {
var overItem = this.findMenuItem_(e.target); var overItem = this.findMenuItem_(/** @type {Element} */(e.target));
this.selectedItem = overItem; this.selectedItem = overItem;
}, },
...@@ -267,7 +267,7 @@ cr.define('cr.ui', function() { ...@@ -267,7 +267,7 @@ cr.define('cr.ui', function() {
/** /**
* The selected menu item. * The selected menu item.
* @type {number} * type {number}
*/ */
cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS, cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS,
selectedIndexChanged); selectedIndexChanged);
......
...@@ -4,28 +4,34 @@ ...@@ -4,28 +4,34 @@
// <include src="../../assert.js"> // <include src="../../assert.js">
cr.exportPath('cr.ui');
/**
* Enum for type of hide. Delayed is used when called by clicking on a
* checkable menu item.
* @enum {number}
*/
cr.ui.HideType = {
INSTANT: 0,
DELAYED: 1
};
cr.define('cr.ui', function() { cr.define('cr.ui', function() {
/** @const */ /** @const */
var Menu = cr.ui.Menu; var Menu = cr.ui.Menu;
/** @const */ /** @const */
var positionPopupAroundElement = cr.ui.positionPopupAroundElement; var HideType = cr.ui.HideType;
/** /** @const */
* Enum for type of hide. Delayed is used when called by clicking on a var positionPopupAroundElement = cr.ui.positionPopupAroundElement;
* checkable menu item.
* @enum {number}
*/
var HideType = {
INSTANT: 0,
DELAYED: 1
};
/** /**
* Creates a new menu button element. * Creates a new menu button element.
* @param {Object=} opt_propertyBag Optional properties. * @param {Object=} opt_propertyBag Optional properties.
* @constructor * @constructor
* @extends {HTMLButtonElement} * @extends {HTMLButtonElement}
* @implements {EventListener}
*/ */
var MenuButton = cr.ui.define('button'); var MenuButton = cr.ui.define('button');
...@@ -92,10 +98,12 @@ cr.define('cr.ui', function() { ...@@ -92,10 +98,12 @@ cr.define('cr.ui', function() {
switch (e.type) { switch (e.type) {
case 'mousedown': case 'mousedown':
if (e.currentTarget == this.ownerDocument) { if (e.currentTarget == this.ownerDocument) {
if (!this.contains(e.target) && !this.menu.contains(e.target)) if (e.target instanceof Element && !this.contains(e.target) &&
!this.menu.contains(e.target)) {
this.hideMenu(); this.hideMenu();
else } else {
e.preventDefault(); e.preventDefault();
}
} else { } else {
if (this.isMenuShown()) { if (this.isMenuShown()) {
this.hideMenu(); this.hideMenu();
...@@ -125,7 +133,8 @@ cr.define('cr.ui', function() { ...@@ -125,7 +133,8 @@ cr.define('cr.ui', function() {
this.classList.remove('using-mouse'); this.classList.remove('using-mouse');
break; break;
case 'focus': case 'focus':
if (!this.contains(e.target) && !this.menu.contains(e.target)) { if (e.target instanceof Element && !this.contains(e.target) &&
!this.menu.contains(e.target)) {
this.hideMenu(); this.hideMenu();
// Show the focus ring on focus - if it's come from a mouse event, // Show the focus ring on focus - if it's come from a mouse event,
// the focus ring will be hidden in the mousedown event handler, // the focus ring will be hidden in the mousedown event handler,
...@@ -188,8 +197,8 @@ cr.define('cr.ui', function() { ...@@ -188,8 +197,8 @@ cr.define('cr.ui', function() {
/** /**
* Hides the menu. If your menu can go out of scope, make sure to call this * Hides the menu. If your menu can go out of scope, make sure to call this
* first. * first.
* @param {HideType=} opt_hideType Type of hide. * @param {cr.ui.HideType=} opt_hideType Type of hide.
* default: HideType.INSTANT. * default: cr.ui.HideType.INSTANT.
*/ */
hideMenu: function(opt_hideType) { hideMenu: function(opt_hideType) {
if (!this.isMenuShown()) if (!this.isMenuShown())
...@@ -275,27 +284,26 @@ cr.define('cr.ui', function() { ...@@ -275,27 +284,26 @@ cr.define('cr.ui', function() {
* Create the images used to style drop-down-style MenuButtons. * Create the images used to style drop-down-style MenuButtons.
* This should be called before creating any MenuButtons that will have the * This should be called before creating any MenuButtons that will have the
* CSS class 'drop-down'. If no colors are specified, defaults will be used. * CSS class 'drop-down'. If no colors are specified, defaults will be used.
* @param {=string} normalColor CSS color for the default button state. * @param {string=} opt_normalColor CSS color for the default button state.
* @param {=string} hoverColor CSS color for the hover button state. * @param {string=} opt_hoverColor CSS color for the hover button state.
* @param {=string} activeColor CSS color for the active button state. * @param {string=} opt_activeColor CSS color for the active button state.
*/ */
MenuButton.createDropDownArrows = function( MenuButton.createDropDownArrows = function(
normalColor, hoverColor, activeColor) { opt_normalColor, opt_hoverColor, opt_activeColor) {
normalColor = normalColor || 'rgb(192, 195, 198)'; opt_normalColor = opt_normalColor || 'rgb(192, 195, 198)';
hoverColor = hoverColor || 'rgb(48, 57, 66)'; opt_hoverColor = opt_hoverColor || 'rgb(48, 57, 66)';
activeColor = activeColor || 'white'; opt_activeColor = opt_activeColor || 'white';
createDropDownArrowCanvas( createDropDownArrowCanvas(
'drop-down-arrow', ARROW_WIDTH, ARROW_HEIGHT, normalColor); 'drop-down-arrow', ARROW_WIDTH, ARROW_HEIGHT, opt_normalColor);
createDropDownArrowCanvas( createDropDownArrowCanvas(
'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, hoverColor); 'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, opt_hoverColor);
createDropDownArrowCanvas( createDropDownArrowCanvas(
'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, activeColor); 'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, opt_activeColor);
}; };
// Export // Export
return { return {
MenuButton: MenuButton, MenuButton: MenuButton,
HideType: HideType
}; };
}); });
...@@ -9,7 +9,8 @@ cr.define('cr.ui', function() { ...@@ -9,7 +9,8 @@ cr.define('cr.ui', function() {
* Creates a new menu item element. * Creates a new menu item element.
* @param {Object=} opt_propertyBag Optional properties. * @param {Object=} opt_propertyBag Optional properties.
* @constructor * @constructor
* @extends {HTMLDivElement} * @extends {HTMLButtonElement}
* @implements {EventListener}
*/ */
var MenuItem = cr.ui.define('div'); var MenuItem = cr.ui.define('div');
...@@ -69,7 +70,7 @@ cr.define('cr.ui', function() { ...@@ -69,7 +70,7 @@ cr.define('cr.ui', function() {
} }
if (typeof command == 'string' && command[0] == '#') { if (typeof command == 'string' && command[0] == '#') {
command = this.ownerDocument.getElementById(command.slice(1)); command = assert(this.ownerDocument.getElementById(command.slice(1)));
cr.ui.decorate(command, Command); cr.ui.decorate(command, Command);
} }
...@@ -183,10 +184,11 @@ cr.define('cr.ui', function() { ...@@ -183,10 +184,11 @@ cr.define('cr.ui', function() {
/** /**
* Handles mouseup events. This dispatches an activate event; if there is an * Handles mouseup events. This dispatches an activate event; if there is an
* associated command, that command is executed. * associated command, that command is executed.
* @param {Event} e The mouseup event object. * @param {!Event} e The mouseup event object.
* @private * @private
*/ */
handleMouseUp_: function(e) { handleMouseUp_: function(e) {
e = /** @type {!MouseEvent} */(e);
// Only dispatch an activate event for left or middle click. // Only dispatch an activate event for left or middle click.
if (e.button > 1) if (e.button > 1)
return; return;
...@@ -243,31 +245,26 @@ cr.define('cr.ui', function() { ...@@ -243,31 +245,26 @@ cr.define('cr.ui', function() {
/** /**
* Whether the menu item is disabled or not. * Whether the menu item is disabled or not.
* @type {boolean}
*/ */
cr.defineProperty(MenuItem, 'disabled', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(MenuItem, 'disabled', cr.PropertyKind.BOOL_ATTR);
/** /**
* Whether the menu item is hidden or not. * Whether the menu item is hidden or not.
* @type {boolean}
*/ */
cr.defineProperty(MenuItem, 'hidden', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(MenuItem, 'hidden', cr.PropertyKind.BOOL_ATTR);
/** /**
* Whether the menu item is selected or not. * Whether the menu item is selected or not.
* @type {boolean}
*/ */
cr.defineProperty(MenuItem, 'selected', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(MenuItem, 'selected', cr.PropertyKind.BOOL_ATTR);
/** /**
* Whether the menu item is checked or not. * Whether the menu item is checked or not.
* @type {boolean}
*/ */
cr.defineProperty(MenuItem, 'checked', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(MenuItem, 'checked', cr.PropertyKind.BOOL_ATTR);
/** /**
* Whether the menu item is checkable or not. * Whether the menu item is checkable or not.
* @type {boolean}
*/ */
cr.defineProperty(MenuItem, 'checkable', cr.PropertyKind.BOOL_ATTR); cr.defineProperty(MenuItem, 'checkable', cr.PropertyKind.BOOL_ATTR);
......
...@@ -6,55 +6,59 @@ ...@@ -6,55 +6,59 @@
* @fileoverview This file provides utility functions for position popups. * @fileoverview This file provides utility functions for position popups.
*/ */
cr.define('cr.ui', function() { cr.exportPath('cr.ui');
/**
* Type def for rects as returned by getBoundingClientRect.
* @typedef {{left: number, top: number, width: number, height: number,
* right: number, bottom: number}}
*/
cr.ui.Rect;
/**
* Enum for defining how to anchor a popup to an anchor element.
* @enum {number}
*/
cr.ui.AnchorType = {
/** /**
* Type def for rects as returned by getBoundingClientRect. * The popup's right edge is aligned with the left edge of the anchor.
* @typedef { {left: number, top: number, width: number, height: number, * The popup's top edge is aligned with the top edge of the anchor.
* right: number, bottom: number}}
*/ */
var Rect; BEFORE: 1, // p: right, a: left, p: top, a: top
/** /**
* Enum for defining how to anchor a popup to an anchor element. * The popop's left edge is aligned with the right edge of the anchor.
* @enum {number} * The popup's top edge is aligned with the top edge of the anchor.
*/ */
var AnchorType = { AFTER: 2, // p: left a: right, p: top, a: top
/**
* The popup's right edge is aligned with the left edge of the anchor. /**
* The popup's top edge is aligned with the top edge of the anchor. * The popop's bottom edge is aligned with the top edge of the anchor.
*/ * The popup's left edge is aligned with the left edge of the anchor.
BEFORE: 1, // p: right, a: left, p: top, a: top */
ABOVE: 3, // p: bottom, a: top, p: left, a: left
/**
* The popop's left edge is aligned with the right edge of the anchor. /**
* The popup's top edge is aligned with the top edge of the anchor. * The popop's top edge is aligned with the bottom edge of the anchor.
*/ * The popup's left edge is aligned with the left edge of the anchor.
AFTER: 2, // p: left a: right, p: top, a: top */
BELOW: 4 // p: top, a: bottom, p: left, a: left
/** };
* The popop's bottom edge is aligned with the top edge of the anchor.
* The popup's left edge is aligned with the left edge of the anchor. cr.define('cr.ui', function() {
*/ /** @const */
ABOVE: 3, // p: bottom, a: top, p: left, a: left var AnchorType = cr.ui.AnchorType;
/**
* The popop's top edge is aligned with the bottom edge of the anchor.
* The popup's left edge is aligned with the left edge of the anchor.
*/
BELOW: 4 // p: top, a: bottom, p: left, a: left
};
/** /**
* Helper function for positionPopupAroundElement and positionPopupAroundRect. * Helper function for positionPopupAroundElement and positionPopupAroundRect.
* @param {!Rect} anchorRect The rect for the anchor. * @param {!cr.ui.Rect} anchorRect The rect for the anchor.
* @param {!HTMLElement} popupElement The element used for the popup. * @param {!HTMLElement} popupElement The element used for the popup.
* @param {AnchorType} type The type of anchoring to do. * @param {cr.ui.AnchorType} type The type of anchoring to do.
* @param {boolean} invertLeftRight Whether to invert the right/left * @param {boolean=} opt_invertLeftRight Whether to invert the right/left
* alignment. * alignment.
*/ */
function positionPopupAroundRect(anchorRect, popupElement, type, function positionPopupAroundRect(anchorRect, popupElement, type,
invertLeftRight) { opt_invertLeftRight) {
var popupRect = popupElement.getBoundingClientRect(); var popupRect = popupElement.getBoundingClientRect();
var availRect; var availRect;
var ownerDoc = popupElement.ownerDocument; var ownerDoc = popupElement.ownerDocument;
...@@ -77,10 +81,10 @@ cr.define('cr.ui', function() { ...@@ -77,10 +81,10 @@ cr.define('cr.ui', function() {
} }
if (cs.direction == 'rtl') if (cs.direction == 'rtl')
invertLeftRight = !invertLeftRight; opt_invertLeftRight = !opt_invertLeftRight;
// Flip BEFORE, AFTER based on alignment. // Flip BEFORE, AFTER based on alignment.
if (invertLeftRight) { if (opt_invertLeftRight) {
if (type == AnchorType.BEFORE) if (type == AnchorType.BEFORE)
type = AnchorType.AFTER; type = AnchorType.AFTER;
else if (type == AnchorType.AFTER) else if (type == AnchorType.AFTER)
...@@ -152,7 +156,7 @@ cr.define('cr.ui', function() { ...@@ -152,7 +156,7 @@ cr.define('cr.ui', function() {
switch (type) { switch (type) {
case AnchorType.BELOW: case AnchorType.BELOW:
case AnchorType.ABOVE: case AnchorType.ABOVE:
if (invertLeftRight) { if (opt_invertLeftRight) {
// align right edges // align right edges
if (anchorRect.right - popupRect.width >= 0) { if (anchorRect.right - popupRect.width >= 0) {
style.right = availRect.width - anchorRect.right + 'px'; style.right = availRect.width - anchorRect.right + 'px';
...@@ -206,7 +210,7 @@ cr.define('cr.ui', function() { ...@@ -206,7 +210,7 @@ cr.define('cr.ui', function() {
* @param {!HTMLElement} anchorElement The element that the popup is anchored * @param {!HTMLElement} anchorElement The element that the popup is anchored
* to. * to.
* @param {!HTMLElement} popupElement The popup element we are positioning. * @param {!HTMLElement} popupElement The popup element we are positioning.
* @param {AnchorType} type The type of anchoring we want. * @param {cr.ui.AnchorType} type The type of anchoring we want.
* @param {boolean} invertLeftRight Whether to invert the right/left * @param {boolean} invertLeftRight Whether to invert the right/left
* alignment. * alignment.
*/ */
...@@ -236,7 +240,6 @@ cr.define('cr.ui', function() { ...@@ -236,7 +240,6 @@ cr.define('cr.ui', function() {
// Export // Export
return { return {
AnchorType: AnchorType,
positionPopupAroundElement: positionPopupAroundElement, positionPopupAroundElement: positionPopupAroundElement,
positionPopupAtPoint: positionPopupAtPoint positionPopupAtPoint: positionPopupAtPoint
}; };
......
...@@ -22,80 +22,71 @@ ...@@ -22,80 +22,71 @@
*/ */
var EventTrackerEntry; var EventTrackerEntry;
// Use an anonymous function to enable strict mode just for this file (which /**
// will be concatenated with other files when embedded in Chrome). * Create an EventTracker to track a set of events.
var EventTracker = (function() { * EventTracker instances are typically tied 1:1 with other objects or
'use strict'; * DOM elements whose listeners should be removed when the object is disposed
* or the corresponding elements are removed from the DOM.
* @constructor
*/
function EventTracker() {
/** /**
* Create an EventTracker to track a set of events. * @type {Array.<EventTrackerEntry>}
* EventTracker instances are typically tied 1:1 with other objects or * @private
* DOM elements whose listeners should be removed when the object is disposed
* or the corresponding elements are removed from the DOM.
* @constructor
*/ */
function EventTracker() { this.listeners_ = [];
/** }
* @type {Array.<EventTrackerEntry>}
* @private
*/
this.listeners_ = [];
}
EventTracker.prototype = {
/**
* Add an event listener - replacement for Node.addEventListener.
* @param {!Node} node The DOM node to add a listener to.
* @param {string} eventType The type of event to subscribe to.
* @param {Function} listener The listener to add.
* @param {boolean=} opt_capture Whether to invoke during the capture phase.
*/
add: function(node, eventType, listener, opt_capture) {
var capture = !!opt_capture;
var h = {
node: node,
eventType: eventType,
listener: listener,
capture: capture,
};
this.listeners_.push(h);
node.addEventListener(eventType, listener, capture);
},
/** EventTracker.prototype = {
* Remove any specified event listeners added with this EventTracker. /**
* @param {!Node} node The DOM node to remove a listener from. * Add an event listener - replacement for Node.addEventListener.
* @param {?string} eventType The type of event to remove. * @param {!Node} node The DOM node to add a listener to.
*/ * @param {string} eventType The type of event to subscribe to.
remove: function(node, eventType) { * @param {Function} listener The listener to add.
this.listeners_ = this.listeners_.filter(function(h) { * @param {boolean=} opt_capture Whether to invoke during the capture phase.
if (h.node == node && (!eventType || (h.eventType == eventType))) { */
EventTracker.removeEventListener_(h); add: function(node, eventType, listener, opt_capture) {
return false; var capture = !!opt_capture;
} var h = {
return true; node: node,
}); eventType: eventType,
}, listener: listener,
capture: capture,
/** };
* Remove all event listeners added with this EventTracker. this.listeners_.push(h);
*/ node.addEventListener(eventType, listener, capture);
removeAll: function() { },
this.listeners_.forEach(EventTracker.removeEventListener_);
this.listeners_ = [];
}
};
/** /**
* Remove a single event listener given it's tracking entry. It's up to the * Remove any specified event listeners added with this EventTracker.
* caller to ensure the entry is removed from listeners_. * @param {!Node} node The DOM node to remove a listener from.
* @param {EventTrackerEntry} h The entry describing the listener to remove. * @param {?string} eventType The type of event to remove.
* @private
*/ */
EventTracker.removeEventListener_ = function(h) { remove: function(node, eventType) {
h.node.removeEventListener(h.eventType, h.listener, h.capture); this.listeners_ = this.listeners_.filter(function(h) {
}; if (h.node == node && (!eventType || (h.eventType == eventType))) {
EventTracker.removeEventListener_(h);
return false;
}
return true;
});
},
return EventTracker; /**
})(); * Remove all event listeners added with this EventTracker.
*/
removeAll: function() {
this.listeners_.forEach(EventTracker.removeEventListener_);
this.listeners_ = [];
}
};
/**
* Remove a single event listener given it's tracking entry. It's up to the
* caller to ensure the entry is removed from listeners_.
* @param {EventTrackerEntry} h The entry describing the listener to remove.
* @private
*/
EventTracker.removeEventListener_ = function(h) {
h.node.removeEventListener(h.eventType, h.listener, h.capture);
};
...@@ -168,14 +168,14 @@ function setQueryParam(location, key, value) { ...@@ -168,14 +168,14 @@ function setQueryParam(location, key, value) {
} }
/** /**
* @param {Node} el An element to search for ancestors with |className|. * @param {Element} el An element to search for ancestors with |className|.
* @param {string} className A class to search for. * @param {string} className A class to search for.
* @return {Node} A node with class of |className| or null if none is found. * @return {Element} A node with class of |className| or null if none is found.
*/ */
function findAncestorByClass(el, className) { function findAncestorByClass(el, className) {
return findAncestor(el, function(el) { return /** @type {Element} */(findAncestor(el, function(el) {
return el.classList && el.classList.contains(className); return el.classList && el.classList.contains(className);
}); }));
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment