Index: chrome/browser/resources/md_history/app.crisper.js |
diff --git a/chrome/browser/resources/md_history/app.crisper.js b/chrome/browser/resources/md_history/app.crisper.js |
index d9c70b5df3bed688349b6c353b73f9ff59e50748..7d847896eddbdaa4e43346d6de0a490433e4d39a 100644 |
--- a/chrome/browser/resources/md_history/app.crisper.js |
+++ b/chrome/browser/resources/md_history/app.crisper.js |
@@ -10746,6 +10746,145 @@ Polymer({ |
Polymer.PaperItemBehavior |
] |
}); |
+// Copyright 2016 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. |
+ |
+/** |
+ * @fileoverview Defines a singleton object, md_history.BrowserService, which |
+ * provides access to chrome.send APIs. |
+ */ |
+ |
+cr.define('md_history', function() { |
+ /** @constructor */ |
+ function BrowserService() { |
+ /** @private {Array<!HistoryEntry>} */ |
+ this.pendingDeleteItems_ = null; |
+ /** @private {PromiseResolver} */ |
+ this.pendingDeletePromise_ = null; |
+ } |
+ |
+ BrowserService.prototype = { |
+ /** |
+ * @param {!Array<!HistoryEntry>} items |
+ * @return {Promise<!Array<!HistoryEntry>>} |
+ */ |
+ deleteItems: function(items) { |
+ if (this.pendingDeleteItems_ != null) { |
+ // There's already a deletion in progress, reject immediately. |
+ return new Promise(function(resolve, reject) { reject(items); }); |
+ } |
+ |
+ var removalList = items.map(function(item) { |
+ return { |
+ url: item.url, |
+ timestamps: item.allTimestamps |
+ }; |
+ }); |
+ |
+ this.pendingDeleteItems_ = items; |
+ this.pendingDeletePromise_ = new PromiseResolver(); |
+ |
+ chrome.send('removeVisits', removalList); |
+ |
+ return this.pendingDeletePromise_.promise; |
+ }, |
+ |
+ /** |
+ * @param {!string} url |
+ */ |
+ removeBookmark: function(url) { |
+ chrome.send('removeBookmark', [url]); |
+ }, |
+ |
+ /** |
+ * @param {string} sessionTag |
+ */ |
+ openForeignSessionAllTabs: function(sessionTag) { |
+ chrome.send('openForeignSession', [sessionTag]); |
+ }, |
+ |
+ /** |
+ * @param {string} sessionTag |
+ * @param {number} windowId |
+ * @param {number} tabId |
+ * @param {MouseEvent} e |
+ */ |
+ openForeignSessionTab: function(sessionTag, windowId, tabId, e) { |
+ chrome.send('openForeignSession', [ |
+ sessionTag, String(windowId), String(tabId), e.button || 0, e.altKey, |
+ e.ctrlKey, e.metaKey, e.shiftKey |
+ ]); |
+ }, |
+ |
+ /** |
+ * @param {string} sessionTag |
+ */ |
+ deleteForeignSession: function(sessionTag) { |
+ chrome.send('deleteForeignSession', [sessionTag]); |
+ }, |
+ |
+ openClearBrowsingData: function() { |
+ chrome.send('clearBrowsingData'); |
+ }, |
+ |
+ /** |
+ * @param {string} histogram |
+ * @param {number} value |
+ * @param {number} max |
+ */ |
+ recordHistogram: function(histogram, value, max) { |
+ chrome.send('metricsHandler:recordInHistogram', [histogram, value, max]); |
+ }, |
+ |
+ /** |
+ * Record an action in UMA. |
+ * @param {string} action The name of the action to be logged. |
+ */ |
+ recordAction: function(action) { |
+ if (action.indexOf('_') == -1) |
+ action = 'HistoryPage_' + action; |
+ chrome.send('metricsHandler:recordAction', [action]); |
+ }, |
+ |
+ /** |
+ * @param {boolean} successful |
+ * @private |
+ */ |
+ resolveDelete_: function(successful) { |
+ if (this.pendingDeleteItems_ == null || |
+ this.pendingDeletePromise_ == null) { |
+ return; |
+ } |
+ |
+ if (successful) |
+ this.pendingDeletePromise_.resolve(this.pendingDeleteItems_); |
+ else |
+ this.pendingDeletePromise_.reject(this.pendingDeleteItems_); |
+ |
+ this.pendingDeleteItems_ = null; |
+ this.pendingDeletePromise_ = null; |
+ }, |
+ }; |
+ |
+ cr.addSingletonGetter(BrowserService); |
+ |
+ return {BrowserService: BrowserService}; |
+}); |
+ |
+/** |
+ * Called by the history backend when deletion was succesful. |
+ */ |
+function deleteComplete() { |
+ md_history.BrowserService.getInstance().resolveDelete_(true); |
+} |
+ |
+/** |
+ * Called by the history backend when the deletion failed. |
+ */ |
+function deleteFailed() { |
+ md_history.BrowserService.getInstance().resolveDelete_(false); |
+}; |
Polymer({ |
is: 'iron-collapse', |
@@ -11360,143 +11499,6 @@ cr.define('cr.icon', function() { |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-/** |
- * @fileoverview Defines a singleton object, md_history.BrowserService, which |
- * provides access to chrome.send APIs. |
- */ |
- |
-cr.define('md_history', function() { |
- /** @constructor */ |
- function BrowserService() { |
- /** @private {Array<!HistoryEntry>} */ |
- this.pendingDeleteItems_ = null; |
- /** @private {PromiseResolver} */ |
- this.pendingDeletePromise_ = null; |
- } |
- |
- BrowserService.prototype = { |
- /** |
- * @param {!Array<!HistoryEntry>} items |
- * @return {Promise<!Array<!HistoryEntry>>} |
- */ |
- deleteItems: function(items) { |
- if (this.pendingDeleteItems_ != null) { |
- // There's already a deletion in progress, reject immediately. |
- return new Promise(function(resolve, reject) { reject(items); }); |
- } |
- |
- var removalList = items.map(function(item) { |
- return { |
- url: item.url, |
- timestamps: item.allTimestamps |
- }; |
- }); |
- |
- this.pendingDeleteItems_ = items; |
- this.pendingDeletePromise_ = new PromiseResolver(); |
- |
- chrome.send('removeVisits', removalList); |
- |
- return this.pendingDeletePromise_.promise; |
- }, |
- |
- /** |
- * @param {!string} url |
- */ |
- removeBookmark: function(url) { |
- chrome.send('removeBookmark', [url]); |
- }, |
- |
- /** |
- * @param {string} sessionTag |
- */ |
- openForeignSessionAllTabs: function(sessionTag) { |
- chrome.send('openForeignSession', [sessionTag]); |
- }, |
- |
- /** |
- * @param {string} sessionTag |
- * @param {number} windowId |
- * @param {number} tabId |
- * @param {MouseEvent} e |
- */ |
- openForeignSessionTab: function(sessionTag, windowId, tabId, e) { |
- chrome.send('openForeignSession', [ |
- sessionTag, String(windowId), String(tabId), e.button || 0, e.altKey, |
- e.ctrlKey, e.metaKey, e.shiftKey |
- ]); |
- }, |
- |
- /** |
- * @param {string} sessionTag |
- */ |
- deleteForeignSession: function(sessionTag) { |
- chrome.send('deleteForeignSession', [sessionTag]); |
- }, |
- |
- openClearBrowsingData: function() { |
- chrome.send('clearBrowsingData'); |
- }, |
- |
- /** |
- * @param {string} histogram |
- * @param {number} value |
- * @param {number} max |
- */ |
- recordHistogram: function(histogram, value, max) { |
- chrome.send('metricsHandler:recordInHistogram', [histogram, value, max]); |
- }, |
- |
- /** |
- * Record an action in UMA. |
- * @param {string} actionDesc The name of the action to be logged. |
- */ |
- recordAction: function(actionDesc) { |
- chrome.send('metricsHandler:recordAction', [actionDesc]); |
- }, |
- |
- /** |
- * @param {boolean} successful |
- * @private |
- */ |
- resolveDelete_: function(successful) { |
- if (this.pendingDeleteItems_ == null || |
- this.pendingDeletePromise_ == null) { |
- return; |
- } |
- |
- if (successful) |
- this.pendingDeletePromise_.resolve(this.pendingDeleteItems_); |
- else |
- this.pendingDeletePromise_.reject(this.pendingDeleteItems_); |
- |
- this.pendingDeleteItems_ = null; |
- this.pendingDeletePromise_ = null; |
- }, |
- }; |
- |
- cr.addSingletonGetter(BrowserService); |
- |
- return {BrowserService: BrowserService}; |
-}); |
- |
-/** |
- * Called by the history backend when deletion was succesful. |
- */ |
-function deleteComplete() { |
- md_history.BrowserService.getInstance().resolveDelete_(true); |
-} |
- |
-/** |
- * Called by the history backend when the deletion failed. |
- */ |
-function deleteFailed() { |
- md_history.BrowserService.getInstance().resolveDelete_(false); |
-}; |
-// Copyright 2016 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. |
- |
Polymer({ |
is: 'history-searched-label', |
@@ -11615,8 +11617,10 @@ cr.define('md_history', function() { |
if (this.$$('#bookmark-star') == this.root.activeElement) |
this.$['menu-button'].focus(); |
- md_history.BrowserService.getInstance() |
- .removeBookmark(this.item.url); |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.removeBookmark(this.item.url); |
+ browserService.recordAction('BookmarkStarClicked'); |
+ |
this.fire('remove-bookmark-stars', this.item.url); |
}, |
@@ -11636,6 +11640,31 @@ cr.define('md_history', function() { |
}, |
/** |
+ * Record metrics when a result is clicked. This is deliberately tied to |
+ * on-click rather than on-tap, as on-click triggers from middle clicks. |
+ */ |
+ onLinkClick_: function() { |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordAction('EntryLinkClick'); |
+ browserService.recordHistogram( |
+ 'HistoryPage.ClickPosition', this.item.index, UMA_MAX_BUCKET_VALUE); |
+ |
+ if (this.item.index <= UMA_MAX_SUBSET_BUCKET_VALUE) { |
+ browserService.recordHistogram( |
+ 'HistoryPage.ClickPositionSubset', this.item.index, |
+ UMA_MAX_SUBSET_BUCKET_VALUE); |
+ } |
+ |
+ if (this.searchTerm) |
+ browserService.recordAction('SearchResultClick'); |
+ }, |
+ |
+ onLinkRightClick_: function() { |
+ md_history.BrowserService.getInstance().recordAction( |
+ 'EntryLinkRightClick'); |
+ }, |
+ |
+ /** |
* Set the favicon image, based on the URL of the history item. |
* @private |
*/ |
@@ -11875,6 +11904,14 @@ var HistoryListBehavior = { |
object: array, |
type: 'splice' |
}); |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordHistogram( |
+ 'HistoryPage.RemoveEntryPosition', index, UMA_MAX_BUCKET_VALUE); |
+ if (index <= UMA_MAX_SUBSET_BUCKET_VALUE) { |
+ browserService.recordHistogram( |
+ 'HistoryPage.RemoveEntryPositionSubset', index, |
+ UMA_MAX_SUBSET_BUCKET_VALUE); |
+ } |
} |
}.bind(this)); |
@@ -12058,6 +12095,19 @@ Polymer({ |
domains: this.createHistoryDomains_(this.historyData) |
}]; |
} |
+ |
+ this.addItemIndexes(); |
+ }, |
+ |
+ addItemIndexes: function() { |
+ var index = 0; |
+ this.groupedHistoryData_.forEach(function(group) { |
+ group.domains.forEach(function(domain) { |
+ domain.visits.forEach(function(visit) { |
+ visit.index = index++; |
+ }); |
+ }); |
+ }); |
}, |
/** |
@@ -14159,6 +14209,10 @@ Polymer({ |
this.lastSearchedTerm_ = this.searchedTerm; |
} |
+ results.forEach(function(item, index) { |
+ item.index = index + (this.historyData_ ? this.historyData_.length : 0); |
+ }); |
+ |
if (this.historyData_) { |
// If we have previously received data, push the new items onto the |
// existing array. |
@@ -14453,6 +14507,11 @@ Polymer({ |
deleteSelectedWithPrompt: function() { |
if (!loadTimeData.getBoolean('allowDeletingHistory')) |
return; |
+ |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordAction('RemoveSelected'); |
+ if (this.searchTerm != '') |
+ browserService.recordAction('SearchResultRemove'); |
this.$.dialog.get().then(function(dialog) { |
dialog.showModal(); |
}); |
@@ -14501,6 +14560,9 @@ Polymer({ |
/** @private */ |
onDialogConfirmTap_: function() { |
+ md_history.BrowserService.getInstance().recordAction( |
+ 'ConfirmRemoveSelected'); |
+ |
this.getSelectedList_().deleteSelected(); |
var dialog = assert(this.$.dialog.getIfExists()); |
dialog.close(); |
@@ -14508,6 +14570,9 @@ Polymer({ |
/** @private */ |
onDialogCancelTap_: function() { |
+ md_history.BrowserService.getInstance().recordAction( |
+ 'CancelRemoveSelected'); |
+ |
var dialog = assert(this.$.dialog.getIfExists()); |
dialog.close(); |
}, |
@@ -14539,6 +14604,9 @@ Polymer({ |
/** @private */ |
onMoreFromSiteTap_: function() { |
+ md_history.BrowserService.getInstance().recordAction( |
+ 'EntryMenuShowMoreFromSite'); |
+ |
var menu = assert(this.$.sharedMenu.getIfExists()); |
this.fire('search-domain', {domain: menu.itemData.item.domain}); |
menu.closeMenu(); |
@@ -14546,10 +14614,11 @@ Polymer({ |
/** @private */ |
onRemoveFromHistoryTap_: function() { |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordAction('EntryMenuRemoveFromHistory'); |
var menu = assert(this.$.sharedMenu.getIfExists()); |
var itemData = menu.itemData; |
- md_history.BrowserService.getInstance() |
- .deleteItems([itemData.item]) |
+ browserService.deleteItems([itemData.item]) |
.then(function(items) { |
this.getSelectedList_().removeItemsByPath([itemData.path]); |
// This unselect-all is to reset the toolbar when deleting a selected |
@@ -14617,7 +14686,11 @@ Polymer({ |
*/ |
openTab_: function(e) { |
var tab = /** @type {ForeignSessionTab} */(e.model.tab); |
- md_history.BrowserService.getInstance().openForeignSessionTab( |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordHistogram( |
+ SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.LINK_CLICKED, |
+ SyncedTabsHistogram.LIMIT); |
+ browserService.openForeignSessionTab( |
this.sessionTag, tab.windowId, tab.sessionId, e); |
e.preventDefault(); |
}, |
@@ -14626,6 +14699,14 @@ Polymer({ |
* Toggles the dropdown display of synced tabs for each device card. |
*/ |
toggleTabCard: function() { |
+ var histogramValue = this.$.collapse.opened ? |
+ SyncedTabsHistogram.COLLAPSE_SESSION : |
+ SyncedTabsHistogram.EXPAND_SESSION; |
+ |
+ md_history.BrowserService.getInstance().recordHistogram( |
+ SYNCED_TABS_HISTOGRAM_NAME, histogramValue, |
+ SyncedTabsHistogram.LIMIT); |
+ |
this.$.collapse.toggle(); |
this.$['dropdown-indicator'].icon = |
this.$.collapse.opened ? 'cr:expand-less' : 'cr:expand-more'; |
@@ -14716,8 +14797,6 @@ Polymer({ |
/** @private */ |
signInState: { |
type: Boolean, |
- // Updated on attach by chrome.sending 'otherDevicesInitialized'. |
- value: loadTimeData.getBoolean('isUserSignedIn'), |
observer: 'signInStateChanged_', |
}, |
@@ -14731,7 +14810,9 @@ Polymer({ |
fetchingSyncedTabs_: { |
type: Boolean, |
value: false, |
- } |
+ }, |
+ |
+ hasSeenForeignData_: Boolean, |
}, |
listeners: { |
@@ -14742,6 +14823,9 @@ Polymer({ |
attached: function() { |
// Update the sign in state. |
chrome.send('otherDevicesInitialized'); |
+ md_history.BrowserService.getInstance().recordHistogram( |
+ SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.INITIALIZED, |
+ SyncedTabsHistogram.LIMIT); |
}, |
/** |
@@ -14801,15 +14885,22 @@ Polymer({ |
onOpenAllTap_: function() { |
var menu = assert(this.$.menu.getIfExists()); |
- md_history.BrowserService.getInstance().openForeignSessionAllTabs( |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordHistogram( |
+ SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.OPEN_ALL, |
+ SyncedTabsHistogram.LIMIT); |
+ browserService.openForeignSessionAllTabs( |
menu.itemData); |
menu.closeMenu(); |
}, |
onDeleteSessionTap_: function() { |
var menu = assert(this.$.menu.getIfExists()); |
- md_history.BrowserService.getInstance().deleteForeignSession( |
- menu.itemData); |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.recordHistogram( |
+ SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.HIDE_FOR_NOW, |
+ SyncedTabsHistogram.LIMIT); |
+ browserService.deleteForeignSession(menu.itemData); |
menu.closeMenu(); |
}, |
@@ -14875,6 +14966,13 @@ Polymer({ |
if (!sessionList) |
return; |
+ if (sessionList.length > 0 && !this.hasSeenForeignData_) { |
+ this.hasSeenForeignData_ = true; |
+ md_history.BrowserService.getInstance().recordHistogram( |
+ SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.HAS_FOREIGN_DATA, |
+ SyncedTabsHistogram.LIMIT); |
+ } |
+ |
// First, update any existing devices that have changed. |
var updateCount = Math.min(sessionList.length, this.syncedDevices_.length); |
for (var i = 0; i < updateCount; i++) { |
@@ -14906,11 +15004,11 @@ Polymer({ |
* different messages are shown when there are no synced tabs. |
* @param {boolean} signInState |
*/ |
- signInStateChanged_: function(signInState) { |
+ signInStateChanged_: function() { |
this.fire('history-view-changed'); |
// User signed out, clear synced device list and show the sign in promo. |
- if (!signInState) { |
+ if (!this.signInState) { |
this.clearDisplayedSyncedDevices_(); |
return; |
} |
@@ -15023,9 +15121,9 @@ Polymer({ |
* @private |
*/ |
onClearBrowsingDataTap_: function(e) { |
- md_history.BrowserService.getInstance().recordAction( |
- 'HistoryPage_InitClearBrowsingData'); |
- md_history.BrowserService.getInstance().openClearBrowsingData(); |
+ var browserService = md_history.BrowserService.getInstance(); |
+ browserService.getInstance().recordAction('InitClearBrowsingData'); |
+ browserService.openClearBrowsingData(); |
e.preventDefault(); |
}, |
@@ -15072,7 +15170,7 @@ Polymer({ |
} |
}, |
- /** @type {!QueryResult} */ |
+ /** @type {!QueryResult} */ |
queryResult_: { |
type: Object, |
value: function() { |
@@ -15092,6 +15190,13 @@ Polymer({ |
// True if the window is narrow enough for the page to have a drawer. |
hasDrawer: Boolean, |
+ |
+ isUserSignedIn_: { |
+ type: Boolean, |
+ // Updated on synced-device-manager attach by chrome.sending |
+ // 'otherDevicesInitialized'. |
+ value: loadTimeData.getBoolean('isUserSignedIn'), |
+ }, |
}, |
observers: [ |
@@ -15162,9 +15267,7 @@ Polymer({ |
toolbar.count = 0; |
}, |
- deleteSelected: function() { |
- this.$.history.deleteSelectedWithPrompt(); |
- }, |
+ deleteSelected: function() { this.$.history.deleteSelectedWithPrompt(); }, |
/** |
* @param {HistoryQuery} info An object containing information about the |
@@ -15183,9 +15286,7 @@ Polymer({ |
/** |
* Focuses the search bar in the toolbar. |
*/ |
- focusToolbarSearchField: function() { |
- this.$.toolbar.showSearchField(); |
- }, |
+ focusToolbarSearchField: function() { this.$.toolbar.showSearchField(); }, |
/** |
* Fired when the user presses 'More from this site'. |
@@ -15219,6 +15320,9 @@ Polymer({ |
searchTermChanged_: function(searchTerm) { |
this.set('queryParams_.q', searchTerm || null); |
this.$['history'].queryHistory(false); |
+ // TODO(tsergeant): Ignore incremental searches in this metric. |
+ if (this.queryState_.searchTerm) |
+ md_history.BrowserService.getInstance().recordAction('Search'); |
}, |
/** |
@@ -15263,11 +15367,7 @@ Polymer({ |
* @param {boolean} isUserSignedIn |
*/ |
updateSignInState: function(isUserSignedIn) { |
- var syncedDeviceManagerElem = |
- /** @type {HistorySyncedDeviceManagerElement} */this |
- .$$('history-synced-device-manager'); |
- if (syncedDeviceManagerElem) |
- syncedDeviceManagerElem.signInState = isUserSignedIn; |
+ this.isUserSignedIn_ = isUserSignedIn; |
}, |
/** |
@@ -15295,9 +15395,7 @@ Polymer({ |
* @param {string} page |
* @private |
*/ |
- routeDataChanged_: function(page) { |
- this.selectedPage_ = page; |
- }, |
+ routeDataChanged_: function(page) { this.selectedPage_ = page; }, |
/** |
* @param {string} selectedPage |
@@ -15305,12 +15403,7 @@ Polymer({ |
*/ |
selectedPageChanged_: function(selectedPage) { |
this.set('routeData_.page', selectedPage); |
- |
- // Log the current view on the next animation frame to allow the iron-pages |
- // to detect that the synced-device-manager has been rendered. |
- requestAnimationFrame(function() { |
- this.recordHistoryView_(); |
- }.bind(this)); |
+ this.recordHistoryView_(); |
}, |
/** |
@@ -15323,9 +15416,7 @@ Polymer({ |
* @return {string} |
* @private |
*/ |
- getSelectedPage_: function(selectedPage, items) { |
- return selectedPage; |
- }, |
+ getSelectedPage_: function(selectedPage, items) { return selectedPage; }, |
/** @private */ |
closeDrawer_: function() { |
@@ -15337,8 +15428,13 @@ Polymer({ |
/** @private */ |
recordHistoryView_: function() { |
var histogramValue = HistoryViewHistogram.END; |
- switch (this.$.content.selectedItem.id) { |
- case 'history': |
+ switch (this.selectedPage_) { |
+ case 'syncedTabs': |
+ histogramValue = this.isUserSignedIn_ ? |
+ HistoryViewHistogram.SYNCED_TABS : |
+ HistoryViewHistogram.SIGNIN_PROMO; |
+ break; |
+ default: |
switch (this.queryState_.range) { |
case HistoryRange.ALL_TIME: |
histogramValue = HistoryViewHistogram.HISTORY; |
@@ -15351,14 +15447,6 @@ Polymer({ |
break; |
} |
break; |
- case 'synced-devices': |
- var syncedDeviceManager = |
- /** @type {HistorySyncedDeviceManagerElement} */ this.$.content |
- .selectedItem; |
- histogramValue = syncedDeviceManager.signInState ? |
- HistoryViewHistogram.SYNCED_TABS : |
- HistoryViewHistogram.SIGNIN_PROMO; |
- break; |
} |
md_history.BrowserService.getInstance().recordHistogram( |