Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Unified Diff: chrome/browser/resources/md_downloads/crisper.js

Issue 1492273002: MD Downloads: limit the amount of downloads we send (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new-dl-data
Patch Set: asdf Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/md_downloads/crisper.js
diff --git a/chrome/browser/resources/md_downloads/crisper.js b/chrome/browser/resources/md_downloads/crisper.js
index ee13e9ccc5999ff5cc0467850c70ed2c6112fb24..c2babd5e2d133eebb712ec59af837f16b4d46472 100644
--- a/chrome/browser/resources/md_downloads/crisper.js
+++ b/chrome/browser/resources/md_downloads/crisper.js
@@ -1553,6 +1553,9 @@ cr.define('downloads', function() {
};
ActionService.prototype = {
+ /** @private {Array<string>} */
+ searchTerms_: [],
+
/** @param {string} id ID of the download to cancel. */
cancel: chromeSendWithId('cancel'),
@@ -1578,15 +1581,17 @@ cr.define('downloads', function() {
/** @param {string} id ID of the download that the user started dragging. */
drag: chromeSendWithId('drag'),
- /** @private {boolean} */
- isSearching_: false,
+ /** Loads more downloads with the current search terms. */
+ loadMore: function() {
+ chrome.send('getDownloads', this.searchTerms_);
+ },
/**
* @return {boolean} Whether the user is currently searching for downloads
* (i.e. has a non-empty search term).
*/
isSearching: function() {
- return this.isSearching_;
+ return this.searchTerms_.length > 0;
},
/** Opens the current local destination for downloads. */
@@ -1614,15 +1619,19 @@ cr.define('downloads', function() {
/** @param {string} searchText What to search for. */
search: function(searchText) {
- if (this.searchText_ == searchText)
- return;
+ var searchTerms = ActionService.splitTerms(searchText);
+ var sameTerms = searchTerms.length == this.searchTerms_.length;
- this.searchText_ = searchText;
+ for (var i = 0; sameTerms && i < searchTerms.length; ++i) {
+ if (searchTerms[i] != this.searchTerms_[i])
+ sameTerms = false;
+ }
- var terms = ActionService.splitTerms(searchText);
- this.isSearching_ = terms.length > 0;
+ if (sameTerms)
+ return;
- chrome.send('getDownloads', terms);
+ this.searchTerms_ = searchTerms;
+ this.loadMore();
},
/**
@@ -10974,46 +10983,10 @@ Polymer({
* Values taken from: http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/keyset.html#KeySet-Set
*/
var KEY_IDENTIFIER = {
+ 'U+0008': 'backspace',
'U+0009': 'tab',
'U+001B': 'esc',
'U+0020': 'space',
- 'U+002A': '*',
- 'U+0030': '0',
- 'U+0031': '1',
- 'U+0032': '2',
- 'U+0033': '3',
- 'U+0034': '4',
- 'U+0035': '5',
- 'U+0036': '6',
- 'U+0037': '7',
- 'U+0038': '8',
- 'U+0039': '9',
- 'U+0041': 'a',
- 'U+0042': 'b',
- 'U+0043': 'c',
- 'U+0044': 'd',
- 'U+0045': 'e',
- 'U+0046': 'f',
- 'U+0047': 'g',
- 'U+0048': 'h',
- 'U+0049': 'i',
- 'U+004A': 'j',
- 'U+004B': 'k',
- 'U+004C': 'l',
- 'U+004D': 'm',
- 'U+004E': 'n',
- 'U+004F': 'o',
- 'U+0050': 'p',
- 'U+0051': 'q',
- 'U+0052': 'r',
- 'U+0053': 's',
- 'U+0054': 't',
- 'U+0055': 'u',
- 'U+0056': 'v',
- 'U+0057': 'w',
- 'U+0058': 'x',
- 'U+0059': 'y',
- 'U+005A': 'z',
'U+007F': 'del'
};
@@ -11025,6 +10998,7 @@ Polymer({
* Values from: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode#Value_of_keyCode
*/
var KEY_CODE = {
+ 8: 'backspace',
9: 'tab',
13: 'enter',
27: 'esc',
@@ -11054,16 +11028,6 @@ Polymer({
};
/**
- * KeyboardEvent.key is mostly represented by printable character made by
- * the keyboard, with unprintable keys labeled nicely.
- *
- * However, on OS X, Alt+char can make a Unicode character that follows an
- * Apple-specific mapping. In this case, we
- * fall back to .keyCode.
- */
- var KEY_CHAR = /[a-z0-9*]/;
-
- /**
* Matches a keyIdentifier string.
*/
var IDENT_CHAR = /U\+/;
@@ -11083,14 +11047,12 @@ Polymer({
var validKey = '';
if (key) {
var lKey = key.toLowerCase();
- if (lKey.length == 1) {
- if (KEY_CHAR.test(lKey)) {
- validKey = lKey;
- }
+ if (lKey === ' ' || SPACE_KEY.test(lKey)) {
+ validKey = 'space';
+ } else if (lKey.length == 1) {
+ validKey = lKey;
} else if (ARROW_KEY.test(lKey)) {
validKey = lKey.replace('arrow', '');
- } else if (SPACE_KEY.test(lKey)) {
- validKey = 'space';
} else if (lKey == 'multiply') {
// numpad '*' can map to Multiply on IE/Windows
validKey = '*';
@@ -11104,8 +11066,11 @@ Polymer({
function transformKeyIdentifier(keyIdent) {
var validKey = '';
if (keyIdent) {
- if (IDENT_CHAR.test(keyIdent)) {
+ if (keyIdent in KEY_IDENTIFIER) {
validKey = KEY_IDENTIFIER[keyIdent];
+ } else if (IDENT_CHAR.test(keyIdent)) {
+ keyIdent = parseInt(keyIdent.replace('U+', '0x'), 16);
+ validKey = String.fromCharCode(keyIdent).toLowerCase();
} else {
validKey = keyIdent.toLowerCase();
}
@@ -11145,15 +11110,24 @@ Polymer({
transformKey(keyEvent.detail.key) || '';
}
- function keyComboMatchesEvent(keyCombo, keyEvent) {
- return normalizedKeyForEvent(keyEvent) === keyCombo.key &&
- !!keyEvent.shiftKey === !!keyCombo.shiftKey &&
- !!keyEvent.ctrlKey === !!keyCombo.ctrlKey &&
- !!keyEvent.altKey === !!keyCombo.altKey &&
- !!keyEvent.metaKey === !!keyCombo.metaKey;
+ function keyComboMatchesEvent(keyCombo, event, eventKey) {
+ return eventKey === keyCombo.key &&
+ (!keyCombo.hasModifiers || (
+ !!event.shiftKey === !!keyCombo.shiftKey &&
+ !!event.ctrlKey === !!keyCombo.ctrlKey &&
+ !!event.altKey === !!keyCombo.altKey &&
+ !!event.metaKey === !!keyCombo.metaKey)
+ );
}
function parseKeyComboString(keyComboString) {
+ if (keyComboString.length === 1) {
+ return {
+ combo: keyComboString,
+ key: keyComboString,
+ event: 'keydown'
+ };
+ }
return keyComboString.split('+').reduce(function(parsedKeyCombo, keyComboPart) {
var eventParts = keyComboPart.split(':');
var keyName = eventParts[0];
@@ -11161,6 +11135,7 @@ Polymer({
if (keyName in MODIFIER_KEYS) {
parsedKeyCombo[MODIFIER_KEYS[keyName]] = true;
+ parsedKeyCombo.hasModifiers = true;
} else {
parsedKeyCombo.key = keyName;
parsedKeyCombo.event = event || 'keydown';
@@ -11173,12 +11148,11 @@ Polymer({
}
function parseEventString(eventString) {
- return eventString.split(' ').map(function(keyComboString) {
+ return eventString.trim().split(' ').map(function(keyComboString) {
return parseKeyComboString(keyComboString);
});
}
-
/**
* `Polymer.IronA11yKeysBehavior` provides a normalized interface for processing
* keyboard commands that pertain to [WAI-ARIA best practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding).
@@ -11274,14 +11248,12 @@ Polymer({
keyboardEventMatchesKeys: function(event, eventString) {
var keyCombos = parseEventString(eventString);
- var index;
-
- for (index = 0; index < keyCombos.length; ++index) {
- if (keyComboMatchesEvent(keyCombos[index], event)) {
+ var eventKey = normalizedKeyForEvent(event);
+ for (var i = 0; i < keyCombos.length; ++i) {
+ if (keyComboMatchesEvent(keyCombos[i], event, eventKey)) {
return true;
}
}
-
return false;
},
@@ -11309,6 +11281,15 @@ Polymer({
for (var eventString in this._imperativeKeyBindings) {
this._addKeyBinding(eventString, this._imperativeKeyBindings[eventString]);
}
+
+ // Give precedence to combos with modifiers to be checked first.
+ for (var eventName in this._keyBindings) {
+ this._keyBindings[eventName].sort(function (kb1, kb2) {
+ var b1 = kb1[0].hasModifiers;
+ var b2 = kb2[0].hasModifiers;
+ return (b1 === b2) ? 0 : b1 ? -1 : 1;
+ })
+ }
},
_addKeyBinding: function(eventString, handlerName) {
@@ -11364,14 +11345,23 @@ Polymer({
event.stopPropagation();
}
- keyBindings.forEach(function(keyBinding) {
- var keyCombo = keyBinding[0];
- var handlerName = keyBinding[1];
+ // if event has been already prevented, don't do anything
+ if (event.defaultPrevented) {
+ return;
+ }
- if (!event.defaultPrevented && keyComboMatchesEvent(keyCombo, event)) {
+ var eventKey = normalizedKeyForEvent(event);
+ for (var i = 0; i < keyBindings.length; i++) {
+ var keyCombo = keyBindings[i][0];
+ var handlerName = keyBindings[i][1];
+ if (keyComboMatchesEvent(keyCombo, event, eventKey)) {
this._triggerKeyHandler(keyCombo, handlerName, event);
+ // exit the loop if eventDefault was prevented
+ if (event.defaultPrevented) {
+ return;
+ }
}
- }, this);
+ }
},
_triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) {
@@ -11609,7 +11599,7 @@ Polymer({
// Ignore the event if this is coming from a focused light child, since that
// element will deal with it.
- if (this.isLightDescendant(target))
+ if (this.isLightDescendant(/** @type {Node} */(target)))
return;
keyboardEvent.preventDefault();
@@ -11626,7 +11616,7 @@ Polymer({
// Ignore the event if this is coming from a focused light child, since that
// element will deal with it.
- if (this.isLightDescendant(target))
+ if (this.isLightDescendant(/** @type {Node} */(target)))
return;
if (this.pressed) {
@@ -12579,6 +12569,15 @@ Polymer({
Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this);
}
}
+ /**
+
+ Fired when the animation finishes.
+ This is useful if you want to wait until
+ the ripple animation finishes to perform some action.
+
+ @event transitionend
+ @param {{node: Object}} detail Contains the animated node.
+ */
});
/**
* `iron-range-behavior` provides the behavior for something with a minimum to maximum range.
@@ -13762,6 +13761,7 @@ Polymer({
for (var i = 0, item; item = this.items[i]; i++) {
var attr = this.attrForItemTitle || 'textContent';
var title = item[attr] || item.getAttribute(attr);
+
if (title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
this._setFocusedItem(item);
break;
@@ -13802,7 +13802,6 @@ Polymer({
} else {
item.removeAttribute('aria-selected');
}
-
Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
},
@@ -13850,18 +13849,18 @@ Polymer({
* @param {CustomEvent} event A key combination event.
*/
_onShiftTabDown: function(event) {
- var oldTabIndex;
+ var oldTabIndex = this.getAttribute('tabindex');
Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
- oldTabIndex = this.getAttribute('tabindex');
+ this._setFocusedItem(null);
this.setAttribute('tabindex', '-1');
this.async(function() {
this.setAttribute('tabindex', oldTabIndex);
Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
- // NOTE(cdata): polymer/polymer#1305
+ // NOTE(cdata): polymer/polymer#1305
}, 1);
},
@@ -13872,23 +13871,27 @@ Polymer({
*/
_onFocus: function(event) {
if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
+ // do not focus the menu itself
return;
}
- // do not focus the menu itself
+
this.blur();
+
// clear the cached focus item
- this._setFocusedItem(null);
this._defaultFocusAsync = this.async(function() {
// focus the selected item when the menu receives focus, or the first item
// if no item is selected
var selectedItem = this.multi ? (this.selectedItems && this.selectedItems[0]) : this.selectedItem;
+
+ this._setFocusedItem(null);
+
if (selectedItem) {
this._setFocusedItem(selectedItem);
} else {
this._setFocusedItem(this.items[0]);
}
- // async 100ms to wait for `select` to get called from `_itemActivate`
- }, 100);
+ // async 1ms to wait for `select` to get called from `_itemActivate`
+ }, 1);
},
/**
@@ -13926,12 +13929,17 @@ Polymer({
* @param {KeyboardEvent} event A keyboard event.
*/
_onKeydown: function(event) {
- if (this.keyboardEventMatchesKeys(event, 'up down esc')) {
- return;
+ if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
+ // all other keys focus the menu item starting with that character
+ this._focusWithKeyboardEvent(event);
}
+ event.stopPropagation();
+ },
- // all other keys focus the menu item starting with that character
- this._focusWithKeyboardEvent(event);
+ // override _activateHandler
+ _activateHandler: function(event) {
+ Polymer.IronSelectableBehavior._activateHandler.call(this, event);
+ event.stopPropagation();
}
};
@@ -16976,6 +16984,10 @@ cr.define('downloads', function() {
loading: true,
},
+ listeners: {
+ 'downloads-list.scroll': 'onListScroll_',
+ },
+
observers: [
'itemsChanged_(items_.*)',
],
@@ -17043,14 +17055,25 @@ cr.define('downloads', function() {
downloads.ActionService.getInstance().undo();
},
+ /**
+ * @param {Event} e
+ * @private
+ */
+ onListScroll_: function(e) {
+ var list = this.$['downloads-list'];
+ if (list.scrollHeight - list.scrollTop - list.offsetHeight <= 100) {
+ // Approaching the end of the scrollback. Attempt to load more items.
+ downloads.ActionService.getInstance().loadMore();
+ }
+ },
+
/** @private */
onLoad_: function() {
cr.ui.decorate('command', cr.ui.Command);
document.addEventListener('canExecute', this.onCanExecute_.bind(this));
document.addEventListener('command', this.onCommand_.bind(this));
- // Shows all downloads.
- downloads.ActionService.getInstance().search('');
+ downloads.ActionService.getInstance().loadMore();
},
/**
@@ -17060,6 +17083,7 @@ cr.define('downloads', function() {
removeItem_: function(index) {
this.splice('items_', index, 1);
this.updateHideDates_(index, index);
+ this.onListScroll_();
},
/**

Powered by Google App Engine
This is Rietveld 408576698