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;
* "background" pages (i.e., those in a dialog that is not the topmost overlay)
* do not receive focus.
* @constructor
* @extends {cr.ui.FocusManager}
*/
function HistoryFocusManager() {
}
......
......@@ -327,6 +327,10 @@ scoped_ptr<base::DictionaryValue> BrowsingHistoryHandler::HistoryEntry::ToValue(
if (domain.empty())
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->SetDouble("time", time.ToJsTime());
......@@ -783,6 +787,10 @@ void BrowsingHistoryHandler::QueryComplete(
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_.SetBoolean("finished", results->reached_beginning());
......
......@@ -301,6 +301,7 @@ var cr = function() {
defineProperty: defineProperty,
dispatchPropertyChange: dispatchPropertyChange,
dispatchSimpleEvent: dispatchSimpleEvent,
exportPath: exportPath,
getUid: getUid,
PropertyKind: PropertyKind,
......
......@@ -5,13 +5,13 @@
cr.define('alertOverlay', function() {
/**
* The confirm <button>.
* @type {HTMLButtonElement}
* @type {HTMLElement}
*/
var okButton;
/**
* The cancel <button>.
* @type {HTMLButtonElement}
* @type {HTMLElement}
*/
var cancelButton;
......@@ -46,13 +46,14 @@ cr.define('alertOverlay', function() {
* no button is shown.
* @param {string=} cancelTitle The title of the cancel button. If undefined
* or empty, no button is shown.
* @param {function=} okCallback A function to be called when the user presses
* the ok button. Can be undefined if |okTitle| is falsey.
* @param {function=} cancelCallback A function to be called when the user
* presses the cancel button. Can be undefined if |cancelTitle| is falsey.
* @param {function()=} opt_okCallback A function to be called when the user
* presses the ok button. Can be undefined if |okTitle| is falsey.
* @param {function()=} opt_cancelCallback A function to be called when the
* user presses the cancel button. Can be undefined if |cancelTitle| is
* falsey.
*/
function setValues(
title, message, okTitle, cancelTitle, okCallback, cancelCallback) {
function setValues(title, message, okTitle, cancelTitle, opt_okCallback,
opt_cancelCallback) {
if (typeof title != 'undefined')
$('alertOverlayTitle').textContent = title;
$('alertOverlayTitle').hidden = typeof title == 'undefined';
......@@ -64,12 +65,12 @@ cr.define('alertOverlay', function() {
if (okTitle)
okButton.textContent = okTitle;
okButton.hidden = !okTitle;
okButton.clickCallback = okCallback;
okButton.clickCallback = opt_okCallback;
if (cancelTitle)
cancelButton.textContent = cancelTitle;
cancelButton.hidden = !cancelTitle;
cancelButton.clickCallback = cancelCallback;
cancelButton.clickCallback = opt_cancelCallback;
};
// Export
......
......@@ -78,7 +78,7 @@ cr.define('cr.ui', function() {
* Initializes the command.
*/
decorate: function() {
CommandManager.init(this.ownerDocument);
CommandManager.init(assert(this.ownerDocument));
if (this.hasAttribute('shortcut'))
this.shortcut = this.getAttribute('shortcut');
......@@ -163,25 +163,21 @@ cr.define('cr.ui', function() {
/**
* The label of the command.
* @type {string}
*/
cr.defineProperty(Command, 'label', cr.PropertyKind.ATTR);
/**
* Whether the command is disabled or not.
* @type {boolean}
*/
cr.defineProperty(Command, 'disabled', cr.PropertyKind.BOOL_ATTR);
/**
* Whether the command is hidden or not.
* @type {boolean}
*/
cr.defineProperty(Command, 'hidden', cr.PropertyKind.BOOL_ATTR);
/**
* Whether the command is checked or not.
* @type {boolean}
*/
cr.defineProperty(Command, 'checked', cr.PropertyKind.BOOL_ATTR);
......@@ -191,18 +187,16 @@ cr.define('cr.ui', function() {
* 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.
* Otherwise, no text is displayed.
*
* @type {boolean}
*/
cr.defineProperty(Command, 'hideShortcutText', cr.PropertyKind.BOOL_ATTR);
/**
* Dispatches a canExecute event on the target.
* @param {cr.ui.Command} command The command that we are testing for.
* @param {Element} target The target element to dispatch the event on.
* @param {!cr.ui.Command} command The command that we are testing for.
* @param {EventTarget} target The target element to dispatch the event on.
*/
function dispatchCanExecuteEvent(command, target) {
var e = new CanExecuteEvent(command, true);
var e = new CanExecuteEvent(command);
target.dispatchEvent(e);
command.disabled = !e.canExecute;
}
......
......@@ -41,10 +41,10 @@ cr.define('cr.ui', function() {
/** @type {!Node} */
this.boundary_ = opt_boundary || document;
/** @private {FocusRow.Delegate|undefined} */
/** @private {cr.ui.FocusRow.Delegate|undefined} */
this.delegate_ = opt_delegate;
/** @private {FocusRow.Observer|undefined} */
/** @private {cr.ui.FocusRow.Observer|undefined} */
this.observer_ = opt_observer;
/** @private {!EventTracker} */
......
......@@ -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.
* @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.
* @private
*/
findMenuItem_: function(el) {
while (el && el.parentNode != this) {
el = el.parentNode;
findMenuItem_: function(node) {
while (node && node.parentNode != this) {
node = node.parentNode;
}
return el ? assertInstanceof(el, MenuItem) : null;
return node ? assertInstanceof(node, MenuItem) : null;
},
/**
......@@ -105,7 +105,7 @@ cr.define('cr.ui', function() {
* @private
*/
handleMouseOver_: function(e) {
var overItem = this.findMenuItem_(e.target);
var overItem = this.findMenuItem_(/** @type {Element} */(e.target));
this.selectedItem = overItem;
},
......@@ -267,7 +267,7 @@ cr.define('cr.ui', function() {
/**
* The selected menu item.
* @type {number}
* type {number}
*/
cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS,
selectedIndexChanged);
......
......@@ -4,28 +4,34 @@
// <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() {
/** @const */
var Menu = cr.ui.Menu;
/** @const */
var positionPopupAroundElement = cr.ui.positionPopupAroundElement;
var HideType = cr.ui.HideType;
/**
* Enum for type of hide. Delayed is used when called by clicking on a
* checkable menu item.
* @enum {number}
*/
var HideType = {
INSTANT: 0,
DELAYED: 1
};
/** @const */
var positionPopupAroundElement = cr.ui.positionPopupAroundElement;
/**
* Creates a new menu button element.
* @param {Object=} opt_propertyBag Optional properties.
* @constructor
* @extends {HTMLButtonElement}
* @implements {EventListener}
*/
var MenuButton = cr.ui.define('button');
......@@ -92,10 +98,12 @@ cr.define('cr.ui', function() {
switch (e.type) {
case 'mousedown':
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();
else
} else {
e.preventDefault();
}
} else {
if (this.isMenuShown()) {
this.hideMenu();
......@@ -125,7 +133,8 @@ cr.define('cr.ui', function() {
this.classList.remove('using-mouse');
break;
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();
// 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,
......@@ -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
* first.
* @param {HideType=} opt_hideType Type of hide.
* default: HideType.INSTANT.
* @param {cr.ui.HideType=} opt_hideType Type of hide.
* default: cr.ui.HideType.INSTANT.
*/
hideMenu: function(opt_hideType) {
if (!this.isMenuShown())
......@@ -275,27 +284,26 @@ cr.define('cr.ui', function() {
* Create the images used to style drop-down-style MenuButtons.
* 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.
* @param {=string} normalColor CSS color for the default button state.
* @param {=string} hoverColor CSS color for the hover button state.
* @param {=string} activeColor CSS color for the active button state.
* @param {string=} opt_normalColor CSS color for the default button state.
* @param {string=} opt_hoverColor CSS color for the hover button state.
* @param {string=} opt_activeColor CSS color for the active button state.
*/
MenuButton.createDropDownArrows = function(
normalColor, hoverColor, activeColor) {
normalColor = normalColor || 'rgb(192, 195, 198)';
hoverColor = hoverColor || 'rgb(48, 57, 66)';
activeColor = activeColor || 'white';
opt_normalColor, opt_hoverColor, opt_activeColor) {
opt_normalColor = opt_normalColor || 'rgb(192, 195, 198)';
opt_hoverColor = opt_hoverColor || 'rgb(48, 57, 66)';
opt_activeColor = opt_activeColor || 'white';
createDropDownArrowCanvas(
'drop-down-arrow', ARROW_WIDTH, ARROW_HEIGHT, normalColor);
'drop-down-arrow', ARROW_WIDTH, ARROW_HEIGHT, opt_normalColor);
createDropDownArrowCanvas(
'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, hoverColor);
'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, opt_hoverColor);
createDropDownArrowCanvas(
'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, activeColor);
'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, opt_activeColor);
};
// Export
return {
MenuButton: MenuButton,
HideType: HideType
};
});
......@@ -9,7 +9,8 @@ cr.define('cr.ui', function() {
* Creates a new menu item element.
* @param {Object=} opt_propertyBag Optional properties.
* @constructor
* @extends {HTMLDivElement}
* @extends {HTMLButtonElement}
* @implements {EventListener}
*/
var MenuItem = cr.ui.define('div');
......@@ -69,7 +70,7 @@ cr.define('cr.ui', function() {
}
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);
}
......@@ -183,10 +184,11 @@ cr.define('cr.ui', function() {
/**
* Handles mouseup events. This dispatches an activate event; if there is an
* associated command, that command is executed.
* @param {Event} e The mouseup event object.
* @param {!Event} e The mouseup event object.
* @private
*/
handleMouseUp_: function(e) {
e = /** @type {!MouseEvent} */(e);
// Only dispatch an activate event for left or middle click.
if (e.button > 1)
return;
......@@ -243,31 +245,26 @@ cr.define('cr.ui', function() {
/**
* Whether the menu item is disabled or not.
* @type {boolean}
*/
cr.defineProperty(MenuItem, 'disabled', cr.PropertyKind.BOOL_ATTR);
/**
* Whether the menu item is hidden or not.
* @type {boolean}
*/
cr.defineProperty(MenuItem, 'hidden', cr.PropertyKind.BOOL_ATTR);
/**
* Whether the menu item is selected or not.
* @type {boolean}
*/
cr.defineProperty(MenuItem, 'selected', cr.PropertyKind.BOOL_ATTR);
/**
* Whether the menu item is checked or not.
* @type {boolean}
*/
cr.defineProperty(MenuItem, 'checked', cr.PropertyKind.BOOL_ATTR);
/**
* Whether the menu item is checkable or not.
* @type {boolean}
*/
cr.defineProperty(MenuItem, 'checkable', cr.PropertyKind.BOOL_ATTR);
......
......@@ -6,55 +6,59 @@
* @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.
* @typedef { {left: number, top: number, width: number, height: number,
* right: number, bottom: number}}
* 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.
*/
var Rect;
BEFORE: 1, // p: right, a: left, p: top, a: top
/**
* Enum for defining how to anchor a popup to an anchor element.
* @enum {number}
* 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.
*/
var AnchorType = {
/**
* 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.
*/
BEFORE: 1, // p: right, a: left, p: top, a: top
/**
* 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.
*/
AFTER: 2, // p: left a: right, p: top, a: top
/**
* 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.
*/
ABOVE: 3, // p: bottom, a: top, p: left, a: left
/**
* 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
};
AFTER: 2, // p: left a: right, p: top, a: top
/**
* 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.
*/
ABOVE: 3, // p: bottom, a: top, p: left, a: left
/**
* 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
};
cr.define('cr.ui', function() {
/** @const */
var AnchorType = cr.ui.AnchorType;
/**
* 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 {AnchorType} type The type of anchoring to do.
* @param {boolean} invertLeftRight Whether to invert the right/left
* @param {cr.ui.AnchorType} type The type of anchoring to do.
* @param {boolean=} opt_invertLeftRight Whether to invert the right/left
* alignment.
*/
function positionPopupAroundRect(anchorRect, popupElement, type,
invertLeftRight) {
opt_invertLeftRight) {
var popupRect = popupElement.getBoundingClientRect();
var availRect;
var ownerDoc = popupElement.ownerDocument;
......@@ -77,10 +81,10 @@ cr.define('cr.ui', function() {
}
if (cs.direction == 'rtl')
invertLeftRight = !invertLeftRight;
opt_invertLeftRight = !opt_invertLeftRight;
// Flip BEFORE, AFTER based on alignment.
if (invertLeftRight) {
if (opt_invertLeftRight) {
if (type == AnchorType.BEFORE)
type = AnchorType.AFTER;
else if (type == AnchorType.AFTER)
......@@ -152,7 +156,7 @@ cr.define('cr.ui', function() {
switch (type) {
case AnchorType.BELOW:
case AnchorType.ABOVE:
if (invertLeftRight) {
if (opt_invertLeftRight) {
// align right edges
if (anchorRect.right - popupRect.width >= 0) {
style.right = availRect.width - anchorRect.right + 'px';
......@@ -206,7 +210,7 @@ cr.define('cr.ui', function() {
* @param {!HTMLElement} anchorElement The element that the popup is anchored
* to.
* @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
* alignment.
*/
......@@ -236,7 +240,6 @@ cr.define('cr.ui', function() {
// Export
return {
AnchorType: AnchorType,
positionPopupAroundElement: positionPopupAroundElement,
positionPopupAtPoint: positionPopupAtPoint
};
......
......@@ -22,80 +22,71 @@
*/
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).
var EventTracker = (function() {
'use strict';
/**
* Create an EventTracker to track a set of events.
* EventTracker instances are typically tied 1:1 with other objects or
* 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.
* EventTracker instances are typically tied 1:1 with other objects or
* DOM elements whose listeners should be removed when the object is disposed
* or the corresponding elements are removed from the DOM.
* @constructor
* @type {Array.<EventTrackerEntry>}
* @private
*/
function EventTracker() {
/**
* @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);
},
this.listeners_ = [];
}
/**
* Remove any specified event listeners added with this EventTracker.
* @param {!Node} node The DOM node to remove a listener from.
* @param {?string} eventType The type of event to remove.
*/
remove: function(node, eventType) {
this.listeners_ = this.listeners_.filter(function(h) {
if (h.node == node && (!eventType || (h.eventType == eventType))) {
EventTracker.removeEventListener_(h);
return false;
}
return true;
});
},
/**
* Remove all event listeners added with this EventTracker.
*/
removeAll: function() {
this.listeners_.forEach(EventTracker.removeEventListener_);
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);
},
/**
* 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
* Remove any specified event listeners added with this EventTracker.
* @param {!Node} node The DOM node to remove a listener from.
* @param {?string} eventType The type of event to remove.
*/
EventTracker.removeEventListener_ = function(h) {
h.node.removeEventListener(h.eventType, h.listener, h.capture);
};
remove: function(node, eventType) {
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) {
}
/**
* @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.
* @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) {
return findAncestor(el, function(el) {
return /** @type {Element} */(findAncestor(el, function(el) {
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