Commit 73e5d0ee authored by tsergeant's avatar tsergeant Committed by Commit bot

MD History: Replace app-route with a custom router

app-route is a fairly heavy-weight element, supporting complex routing
patterns designed for large pages. This is unnecessary for MD History,
which currently has one routing pattern and one query parameter.

This CL replaces app-route with a custom router, <history-router>, which
is responsible for two-way binding between the page state and the page
URL. This also refactors handling of search terms elsewhere in the app
to ensure that changes to the search term are reflected correctly across
the page.

This CL has a small positive impact on load time (~20ms on a Z620), code
health (all routing is handled in one place) and binary size (app-route
can be deleted from the binary).

BUG=629710
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2352293002
Cr-Commit-Position: refs/heads/master@{#420590}
parent fc62aaa4
...@@ -261,6 +261,8 @@ ...@@ -261,6 +261,8 @@
<include name="IDR_MD_HISTORY_LAZY_LOAD_HTML" file="resources\md_history\lazy_load.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_LAZY_LOAD_HTML" file="resources\md_history\lazy_load.html" type="BINDATA" />
<include name="IDR_MD_HISTORY_LIST_CONTAINER_HTML" file="resources\md_history\list_container.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_LIST_CONTAINER_HTML" file="resources\md_history\list_container.html" type="BINDATA" />
<include name="IDR_MD_HISTORY_LIST_CONTAINER_JS" file="resources\md_history\list_container.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_LIST_CONTAINER_JS" file="resources\md_history\list_container.js" type="BINDATA" />
<include name="IDR_MD_HISTORY_ROUTER_HTML" file="resources\md_history\router.html" type="BINDATA" />
<include name="IDR_MD_HISTORY_ROUTER_JS" file="resources\md_history\router.js" type="BINDATA" />
<include name="IDR_MD_HISTORY_SEARCHED_LABEL_HTML" file="resources\md_history\searched_label.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_SEARCHED_LABEL_HTML" file="resources\md_history\searched_label.html" type="BINDATA" />
<include name="IDR_MD_HISTORY_SEARCHED_LABEL_JS" file="resources\md_history\searched_label.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_SEARCHED_LABEL_JS" file="resources\md_history\searched_label.js" type="BINDATA" />
<include name="IDR_MD_HISTORY_SHARED_STYLE_HTML" file="resources\md_history\shared_style.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_SHARED_STYLE_HTML" file="resources\md_history\shared_style.html" type="BINDATA" />
......
<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/html/cr/ui.html"> <link rel="import" href="chrome://resources/html/cr/ui.html">
<link rel="import" href="chrome://resources/html/cr/ui/command.html"> <link rel="import" href="chrome://resources/html/cr/ui/command.html">
<link rel="import" href="chrome://resources/polymer/v1_0/app-route/app-location.html">
<link rel="import" href="chrome://resources/polymer/v1_0/app-route/app-route.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-media-query/iron-media-query.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-media-query/iron-media-query.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-scroll-target-behavior/iron-scroll-target-behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-scroll-target-behavior/iron-scroll-target-behavior.html">
<link rel="import" href="chrome://history/history_toolbar.html"> <link rel="import" href="chrome://history/history_toolbar.html">
<link rel="import" href="chrome://history/list_container.html"> <link rel="import" href="chrome://history/list_container.html">
<link rel="import" href="chrome://history/side_bar.html"> <link rel="import" href="chrome://history/router.html">
<link rel="import" href="chrome://history/shared_style.html"> <link rel="import" href="chrome://history/shared_style.html">
<link rel="import" href="chrome://history/side_bar.html">
<link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<!-- Lazy loaded: history-synced-device-manager, app-drawer. --> <!-- Lazy loaded: history-synced-device-manager, app-drawer. -->
...@@ -87,10 +86,9 @@ ...@@ -87,10 +86,9 @@
opacity: 1; opacity: 1;
} }
</style> </style>
<app-location route="{{route_}}"></app-location> <history-router selected-page="{{selectedPage_}}"
<app-route route="{{route_}}" pattern="/:page" data="{{routeData_}}" query-state="{{queryState_}}">
query-params="{{queryParams_}}"> </history-router>
</app-route>
<history-toolbar id="toolbar" <history-toolbar id="toolbar"
spinner-active="[[shouldShowSpinner_(queryState_.querying, spinner-active="[[shouldShowSpinner_(queryState_.querying,
queryState_.incremental, queryState_.incremental,
...@@ -105,8 +103,8 @@ ...@@ -105,8 +103,8 @@
</history-toolbar> </history-toolbar>
<div id="main-container"> <div id="main-container">
<history-side-bar id="content-side-bar" selected-page="[[selectedPage_]]" <history-side-bar id="content-side-bar" selected-page="{{selectedPage_}}"
route="[[route_]]" show-footer="[[showSidebarFooter]]" show-footer="[[showSidebarFooter]]"
hidden$="[[hasDrawer_]]"> hidden$="[[hasDrawer_]]">
</history-side-bar> </history-side-bar>
<iron-pages id="content" attr-for-selected="path" <iron-pages id="content" attr-for-selected="path"
...@@ -134,8 +132,8 @@ ...@@ -134,8 +132,8 @@
<div id="drawer-header"> <div id="drawer-header">
<h1>$i18n{title}</h1> <h1>$i18n{title}</h1>
</div> </div>
<history-side-bar id="drawer-side-bar" selected-page="[[selectedPage_]]" <history-side-bar id="drawer-side-bar" selected-page="{{selectedPage_}}"
route="[[route_]]" show-footer="[[showSidebarFooter]]" drawer> show-footer="[[showSidebarFooter]]" drawer>
</history-side-bar> </history-side-bar>
</app-drawer> </app-drawer>
</template> </template>
......
...@@ -31,7 +31,7 @@ Polymer({ ...@@ -31,7 +31,7 @@ Polymer({
hasSyncedResults: Boolean, hasSyncedResults: Boolean,
// The id of the currently selected page. // The id of the currently selected page.
selectedPage_: {type: String, observer: 'unselectAll'}, selectedPage_: {type: String, observer: 'selectedPageChanged_'},
// Whether domain-grouped history is enabled. // Whether domain-grouped history is enabled.
grouped_: {type: Boolean, reflectToAttribute: true}, grouped_: {type: Boolean, reflectToAttribute: true},
...@@ -69,12 +69,6 @@ Polymer({ ...@@ -69,12 +69,6 @@ Polymer({
} }
}, },
// Route data for the current page.
routeData_: Object,
// The query params for the page.
queryParams_: Object,
// True if the window is narrow enough for the page to have a drawer. // True if the window is narrow enough for the page to have a drawer.
hasDrawer_: Boolean, hasDrawer_: Boolean,
...@@ -92,24 +86,12 @@ Polymer({ ...@@ -92,24 +86,12 @@ Polymer({
} }
}, },
observers: [
// routeData_.page <=> selectedPage
'routeDataChanged_(routeData_.page)',
'selectedPageChanged_(selectedPage_)',
// queryParams_.q <=> queryState.searchTerm
'searchTermChanged_(queryState_.searchTerm)',
'searchQueryParamChanged_(queryParams_.q)',
],
// TODO(calamity): Replace these event listeners with data bound properties. // TODO(calamity): Replace these event listeners with data bound properties.
listeners: { listeners: {
'cr-menu-tap': 'onMenuTap_', 'cr-menu-tap': 'onMenuTap_',
'history-checkbox-select': 'checkboxSelected', 'history-checkbox-select': 'checkboxSelected',
'unselect-all': 'unselectAll', 'unselect-all': 'unselectAll',
'delete-selected': 'deleteSelected', 'delete-selected': 'deleteSelected',
'search-domain': 'searchDomain_',
'history-close-drawer': 'closeDrawer_', 'history-close-drawer': 'closeDrawer_',
'history-view-changed': 'historyViewChanged_', 'history-view-changed': 'historyViewChanged_',
}, },
...@@ -121,12 +103,6 @@ Polymer({ ...@@ -121,12 +103,6 @@ Polymer({
cr.ui.decorate('command', cr.ui.Command); cr.ui.decorate('command', cr.ui.Command);
document.addEventListener('canExecute', this.onCanExecute_.bind(this)); document.addEventListener('canExecute', this.onCanExecute_.bind(this));
document.addEventListener('command', this.onCommand_.bind(this)); document.addEventListener('command', this.onCommand_.bind(this));
// Redirect legacy search URLs to URLs compatible with material history.
if (window.location.hash) {
window.location.href = window.location.href.split('#')[0] + '?' +
window.location.hash.substr(1);
}
}, },
onFirstRender: function() { onFirstRender: function() {
...@@ -148,7 +124,8 @@ Polymer({ ...@@ -148,7 +124,8 @@ Polymer({
/** Overridden from IronScrollTargetBehavior */ /** Overridden from IronScrollTargetBehavior */
_scrollHandler: function() { _scrollHandler: function() {
this.toolbarShadow_ = this.scrollTarget.scrollTop != 0; if (this.scrollTarget)
this.toolbarShadow_ = this.scrollTarget.scrollTop != 0;
}, },
/** @private */ /** @private */
...@@ -203,12 +180,6 @@ Polymer({ ...@@ -203,12 +180,6 @@ Polymer({
*/ */
focusToolbarSearchField: function() { this.$.toolbar.showSearchField(); }, focusToolbarSearchField: function() { this.$.toolbar.showSearchField(); },
/**
* Fired when the user presses 'More from this site'.
* @param {{detail: {domain: string}}} e
*/
searchDomain_: function(e) { this.$.toolbar.setSearchTerm(e.detail.domain); },
/** /**
* @param {Event} e * @param {Event} e
* @private * @private
...@@ -220,7 +191,7 @@ Polymer({ ...@@ -220,7 +191,7 @@ Polymer({
e.canExecute = true; e.canExecute = true;
break; break;
case 'slash-command': case 'slash-command':
e.canExecute = !this.$.toolbar.searchBar.isSearchFocused(); e.canExecute = !this.$.toolbar.searchField.isSearchFocused();
break; break;
case 'delete-command': case 'delete-command':
e.canExecute = this.$.toolbar.count > 0; e.canExecute = this.$.toolbar.count > 0;
...@@ -228,26 +199,6 @@ Polymer({ ...@@ -228,26 +199,6 @@ Polymer({
} }
}, },
/**
* @param {string} searchTerm
* @private
*/
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');
},
/**
* @param {string} searchQuery
* @private
*/
searchQueryParamChanged_: function(searchQuery) {
this.$.toolbar.setSearchTerm(searchQuery || '');
},
/** /**
* @param {Event} e * @param {Event} e
* @private * @private
...@@ -324,17 +275,10 @@ Polymer({ ...@@ -324,17 +275,10 @@ Polymer({
}, },
/** /**
* @param {string} page
* @private
*/
routeDataChanged_: function(page) { this.selectedPage_ = page; },
/**
* @param {string} selectedPage
* @private * @private
*/ */
selectedPageChanged_: function(selectedPage) { selectedPageChanged_: function() {
this.set('routeData_.page', selectedPage); this.unselectAll();
this.historyViewChanged_(); this.historyViewChanged_();
}, },
...@@ -343,7 +287,12 @@ Polymer({ ...@@ -343,7 +287,12 @@ Polymer({
// This allows the synced-device-manager to render so that it can be set as // This allows the synced-device-manager to render so that it can be set as
// the scroll target. // the scroll target.
requestAnimationFrame(function() { requestAnimationFrame(function() {
this.scrollTarget = this.$.content.selectedItem.getContentScrollTarget(); // <iron-pages> can occasionally end up with no item selected during
// tests.
if (!this.$.content.selectedItem)
return;
this.scrollTarget =
this.$.content.selectedItem.getContentScrollTarget();
this._scrollHandler(); this._scrollHandler();
}.bind(this)); }.bind(this));
this.recordHistoryPageView_(); this.recordHistoryPageView_();
......
...@@ -41,15 +41,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN ...@@ -41,15 +41,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</head><body><div hidden="" by-vulcanize=""><dom-module id="app-location" assetpath="chrome://resources/polymer/v1_0/app-route/" css-build="shadow"> </head><body><div hidden="" by-vulcanize=""><dom-module id="iron-pages" assetpath="chrome://resources/polymer/v1_0/iron-pages/" css-build="shadow">
<template>
<iron-location path="{{__path}}" query="{{__query}}" hash="{{__hash}}" url-space-regex="{{urlSpaceRegex}}">
</iron-location>
<iron-query-params params-string="{{__query}}" params-object="{{queryParams}}">
</iron-query-params>
</template>
</dom-module>
<dom-module id="iron-pages" assetpath="chrome://resources/polymer/v1_0/iron-pages/" css-build="shadow">
<template> <template>
<style scope="iron-pages">:host { <style scope="iron-pages">:host {
...@@ -3573,6 +3565,14 @@ dialog .body { ...@@ -3573,6 +3565,14 @@ dialog .body {
</template> </template>
</template> </template>
</dom-module> </dom-module>
<dom-module id="history-router" assetpath="chrome://history/" css-build="shadow">
<template>
<iron-location path="{{path_}}" query="{{query_}}"></iron-location>
<iron-query-params params-string="{{query_}}" params-object="{{queryParams_}}">
</iron-query-params>
</template>
</dom-module>
<dom-module id="history-side-bar" assetpath="chrome://history/" css-build="shadow"> <dom-module id="history-side-bar" assetpath="chrome://history/" css-build="shadow">
<template> <template>
<style scope="history-side-bar">[hidden] { <style scope="history-side-bar">[hidden] {
...@@ -3725,12 +3725,12 @@ iron-selector > a.iron-selected { ...@@ -3725,12 +3725,12 @@ iron-selector > a.iron-selected {
</style> </style>
<iron-selector id="menu" selected="[[selectedPage]]" selectable=".page-item" attr-for-selected="path" fallback-selection="history" on-iron-activate="onSelectorActivate_"> <iron-selector id="menu" selected="{{selectedPage}}" selectable=".page-item" attr-for-selected="path" fallback-selection="history" on-iron-activate="onSelectorActivate_">
<a href="/[[getQueryString_(route)]]" class="page-item" path="history"> <a href="/" class="page-item" path="history" on-click="onItemClick_">
$i18n{historyMenuItem} $i18n{historyMenuItem}
<paper-ripple></paper-ripple> <paper-ripple></paper-ripple>
</a> </a>
<a href="/syncedTabs[[getQueryString_(route)]]" class="page-item" path="syncedTabs"> <a href="/syncedTabs" class="page-item" path="syncedTabs" on-click="onItemClick_">
$i18n{openTabsMenuItem} $i18n{openTabsMenuItem}
<paper-ripple></paper-ripple> <paper-ripple></paper-ripple>
</a> </a>
...@@ -3898,16 +3898,15 @@ h1 { ...@@ -3898,16 +3898,15 @@ h1 {
} }
</style> </style>
<app-location route="{{route_}}"></app-location> <history-router selected-page="{{selectedPage_}}" query-state="{{queryState_}}">
<app-route route="{{route_}}" pattern="/:page" data="{{routeData_}}" query-params="{{queryParams_}}"> </history-router>
</app-route>
<history-toolbar id="toolbar" spinner-active="[[shouldShowSpinner_(queryState_.querying, <history-toolbar id="toolbar" spinner-active="[[shouldShowSpinner_(queryState_.querying,
queryState_.incremental, queryState_.incremental,
queryState_.searchTerm)]]" is-grouped-mode="{{grouped_}}" grouped-range="{{queryState_.range}}" search-term="{{queryState_.searchTerm}}" query-start-time="[[queryResult_.info.queryStartTime]]" query-end-time="[[queryResult_.info.queryEndTime]]" has-drawer="[[hasDrawer_]]" show-sync-notice="[[showSyncNotice_(hasSyncedResults, selectedPage_)]]"> queryState_.searchTerm)]]" is-grouped-mode="{{grouped_}}" grouped-range="{{queryState_.range}}" search-term="{{queryState_.searchTerm}}" query-start-time="[[queryResult_.info.queryStartTime]]" query-end-time="[[queryResult_.info.queryEndTime]]" has-drawer="[[hasDrawer_]]" show-sync-notice="[[showSyncNotice_(hasSyncedResults, selectedPage_)]]">
</history-toolbar> </history-toolbar>
<div id="main-container"> <div id="main-container">
<history-side-bar id="content-side-bar" selected-page="[[selectedPage_]]" route="[[route_]]" show-footer="[[showSidebarFooter]]" hidden$="[[hasDrawer_]]"> <history-side-bar id="content-side-bar" selected-page="{{selectedPage_}}" show-footer="[[showSidebarFooter]]" hidden$="[[hasDrawer_]]">
</history-side-bar> </history-side-bar>
<iron-pages id="content" attr-for-selected="path" fallback-selection="history" selected="[[getSelectedPage_(selectedPage_, items)]]" items="{{items}}"> <iron-pages id="content" attr-for-selected="path" fallback-selection="history" selected="[[getSelectedPage_(selectedPage_, items)]]" items="{{items}}">
<history-list-container id="history" query-state="{{queryState_}}" query-result="[[queryResult_]]" grouped="[[grouped_]]" grouped-range="{{queryState_.range}}" path="history"> <history-list-container id="history" query-state="{{queryState_}}" query-result="[[queryResult_]]" grouped="[[grouped_]]" grouped-range="{{queryState_.range}}" path="history">
...@@ -3925,7 +3924,7 @@ h1 { ...@@ -3925,7 +3924,7 @@ h1 {
<div id="drawer-header"> <div id="drawer-header">
<h1>$i18n{title}</h1> <h1>$i18n{title}</h1>
</div> </div>
<history-side-bar id="drawer-side-bar" selected-page="[[selectedPage_]]" route="[[route_]]" show-footer="[[showSidebarFooter]]" drawer=""> <history-side-bar id="drawer-side-bar" selected-page="{{selectedPage_}}" show-footer="[[showSidebarFooter]]" drawer="">
</history-side-bar> </history-side-bar>
</app-drawer> </app-drawer>
</template> </template>
......
...@@ -122,6 +122,10 @@ ...@@ -122,6 +122,10 @@
], ],
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
}, },
{
'target_name': 'router',
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{ {
'target_name': 'side_bar', 'target_name': 'side_bar',
'dependencies': [ 'dependencies': [
......
...@@ -26,6 +26,7 @@ Polymer({ ...@@ -26,6 +26,7 @@ Polymer({
// as the user types. // as the user types.
searchTerm: { searchTerm: {
type: String, type: String,
observer: 'searchTermChanged_',
notify: true, notify: true,
}, },
...@@ -74,6 +75,16 @@ Polymer({ ...@@ -74,6 +75,16 @@ Polymer({
}, },
}, },
/** @return {CrToolbarSearchFieldElement} */
get searchField() {
return /** @type {CrToolbarElement} */ (this.$['main-toolbar'])
.getSearchField();
},
showSearchField: function() {
this.searchField.showAndFocus();
},
/** /**
* Changes the toolbar background color depending on whether any history items * Changes the toolbar background color depending on whether any history items
* are currently selected. * are currently selected.
...@@ -86,17 +97,12 @@ Polymer({ ...@@ -86,17 +97,12 @@ Polymer({
/** /**
* When changing the search term externally, update the search field to * When changing the search term externally, update the search field to
* reflect the new search term. * reflect the new search term.
* @param {string} search
*/ */
setSearchTerm: function(search) { searchTermChanged_: function() {
if (this.searchTerm == search) if (this.searchField.getValue() != this.searchTerm) {
return; this.searchField.showAndFocus();
this.searchField.setValue(this.searchTerm);
this.searchTerm = search; }
var searchField = /** @type {!CrToolbarElement} */(this.$['main-toolbar'])
.getSearchField();
searchField.showAndFocus();
searchField.setValue(search);
}, },
/** @private */ /** @private */
...@@ -130,16 +136,6 @@ Polymer({ ...@@ -130,16 +136,6 @@ Polymer({
this.fire('delete-selected'); this.fire('delete-selected');
}, },
get searchBar() {
return this.$['main-toolbar'].getSearchField();
},
showSearchField: function() {
/** @type {!CrToolbarElement} */(this.$['main-toolbar'])
.getSearchField()
.showAndFocus();
},
/** /**
* If the user is a supervised user the delete button is not shown. * If the user is a supervised user the delete button is not shown.
* @private * @private
......
...@@ -22,6 +22,10 @@ Polymer({ ...@@ -22,6 +22,10 @@ Polymer({
queryResult: Object, queryResult: Object,
}, },
observers: [
'searchTermChanged_(queryState.searchTerm)',
],
listeners: { listeners: {
'history-list-scrolled': 'closeMenu_', 'history-list-scrolled': 'closeMenu_',
'load-more-history': 'loadMoreHistory_', 'load-more-history': 'loadMoreHistory_',
...@@ -141,6 +145,14 @@ Polymer({ ...@@ -141,6 +145,14 @@ Polymer({
this.fire('history-view-changed'); this.fire('history-view-changed');
}, },
/** @private */
searchTermChanged_: function() {
this.queryHistory(false);
// TODO(tsergeant): Ignore incremental searches in this metric.
if (this.queryState.searchTerm)
md_history.BrowserService.getInstance().recordAction('Search');
},
/** @private */ /** @private */
loadMoreHistory_: function() { this.queryHistory(true); }, loadMoreHistory_: function() { this.queryHistory(true); },
...@@ -214,7 +226,7 @@ Polymer({ ...@@ -214,7 +226,7 @@ Polymer({
'EntryMenuShowMoreFromSite'); 'EntryMenuShowMoreFromSite');
var menu = assert(this.$.sharedMenu.getIfExists()); var menu = assert(this.$.sharedMenu.getIfExists());
this.fire('search-domain', {domain: menu.itemData.item.domain}); this.set('queryState.searchTerm', menu.itemData.item.domain);
menu.closeMenu(); menu.closeMenu();
}, },
......
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-location/iron-location.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-location/iron-query-params.html">
<dom-module id="history-router">
<template>
<iron-location path="{{path_}}" query="{{query_}}"></iron-location>
<iron-query-params params-string="{{query_}}"
params-object="{{queryParams_}}">
</iron-query-params>
</template>
<script src="chrome://history/router.js"></script>
</dom-module>
// 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-router',
properties: {
selectedPage: {
type: String,
observer: 'serializePath_',
notify: true,
},
queryState: {
type: Object,
notify: true
},
path_: {
type: String,
observer: 'pathChanged_'
},
queryParams_: Object,
},
observers: [
'queryParamsChanged_(queryParams_.*)',
'searchTermChanged_(queryState.searchTerm)',
],
/** @override */
attached: function() {
// Redirect legacy search URLs to URLs compatible with material history.
if (window.location.hash) {
window.location.href = window.location.href.split('#')[0] + '?' +
window.location.hash.substr(1);
}
},
/** @private */
serializePath_: function() {
var page = this.selectedPage == 'history' ? '' : this.selectedPage;
this.path_ = '/' + page;
},
/** @private */
pathChanged_: function() {
var sections = this.path_.substr(1).split('/');
this.selectedPage = sections[0] || 'history';
},
/** @private */
queryParamsChanged_: function() {
this.set('queryState.searchTerm', this.queryParams_.q || '');
},
/** @private */
searchTermChanged_: function() {
this.set('queryParams_.q', this.queryState.searchTerm || null);
},
});
...@@ -79,16 +79,16 @@ ...@@ -79,16 +79,16 @@
} }
</style> </style>
<iron-selector id="menu" selected="[[selectedPage]]" <iron-selector id="menu" selected="{{selectedPage}}"
selectable=".page-item" attr-for-selected="path" selectable=".page-item" attr-for-selected="path"
fallback-selection="history" fallback-selection="history"
on-iron-activate="onSelectorActivate_"> on-iron-activate="onSelectorActivate_">
<a href="/[[getQueryString_(route)]]" class="page-item" path="history"> <a href="/" class="page-item" path="history" on-click="onItemClick_">
$i18n{historyMenuItem} $i18n{historyMenuItem}
<paper-ripple></paper-ripple> <paper-ripple></paper-ripple>
</a> </a>
<a href="/syncedTabs[[getQueryString_(route)]]" class="page-item" <a href="/syncedTabs" class="page-item" path="syncedTabs"
path="syncedTabs"> on-click="onItemClick_">
$i18n{openTabsMenuItem} $i18n{openTabsMenuItem}
<paper-ripple></paper-ripple> <paper-ripple></paper-ripple>
</a> </a>
......
...@@ -10,8 +10,6 @@ Polymer({ ...@@ -10,8 +10,6 @@ Polymer({
properties: { properties: {
selectedPage: {type: String, notify: true}, selectedPage: {type: String, notify: true},
route: Object,
showFooter: Boolean, showFooter: Boolean,
// If true, the sidebar is contained within an app-drawer. // If true, the sidebar is contained within an app-drawer.
...@@ -49,8 +47,11 @@ Polymer({ ...@@ -49,8 +47,11 @@ Polymer({
}, },
/** /**
* @param {Object} route * Prevent clicks on sidebar items from navigating. These are only links for
* accessibility purposes, taps are handled separately by <iron-selector>.
* @private * @private
*/ */
getQueryString_: function(route) { return window.location.search; } onItemClick_: function(e) {
e.preventDefault();
},
}); });
...@@ -175,6 +175,10 @@ content::WebUIDataSource* CreateMdHistoryUIHTMLSource(Profile* profile) { ...@@ -175,6 +175,10 @@ content::WebUIDataSource* CreateMdHistoryUIHTMLSource(Profile* profile) {
IDR_MD_HISTORY_LIST_CONTAINER_HTML); IDR_MD_HISTORY_LIST_CONTAINER_HTML);
source->AddResourcePath("list_container.js", source->AddResourcePath("list_container.js",
IDR_MD_HISTORY_LIST_CONTAINER_JS); IDR_MD_HISTORY_LIST_CONTAINER_JS);
source->AddResourcePath("router.html",
IDR_MD_HISTORY_ROUTER_HTML);
source->AddResourcePath("router.js",
IDR_MD_HISTORY_ROUTER_JS);
source->AddResourcePath("searched_label.html", source->AddResourcePath("searched_label.html",
IDR_MD_HISTORY_SEARCHED_LABEL_HTML); IDR_MD_HISTORY_SEARCHED_LABEL_HTML);
source->AddResourcePath("searched_label.js", source->AddResourcePath("searched_label.js",
......
...@@ -9,15 +9,21 @@ cr.define('md_history.history_routing_test', function() { ...@@ -9,15 +9,21 @@ cr.define('md_history.history_routing_test', function() {
var list; var list;
var toolbar; var toolbar;
suiteSetup(function() { function navigateTo(route) {
app = $('history-app'); window.history.replaceState({}, '', route);
window.dispatchEvent(new CustomEvent('location-changed'));
}
setup(function() {
assertEquals('chrome://history/', window.location.href);
app = replaceApp();
sidebar = app.$['content-side-bar'] sidebar = app.$['content-side-bar']
toolbar = app.$['toolbar']; toolbar = app.$['toolbar'];
}); });
test('changing route changes active view', function() { test('changing route changes active view', function() {
assertEquals('history', app.$.content.selected); assertEquals('history', app.$.content.selected);
app.set('routeData_.page', 'syncedTabs'); navigateTo('/syncedTabs');
return flush().then(function() { return flush().then(function() {
assertEquals('syncedTabs', app.$.content.selected); assertEquals('syncedTabs', app.$.content.selected);
assertEquals('chrome://history/syncedTabs', window.location.href); assertEquals('chrome://history/syncedTabs', window.location.href);
...@@ -26,53 +32,55 @@ cr.define('md_history.history_routing_test', function() { ...@@ -26,53 +32,55 @@ cr.define('md_history.history_routing_test', function() {
test('route updates from sidebar', function() { test('route updates from sidebar', function() {
var menu = sidebar.$.menu; var menu = sidebar.$.menu;
assertEquals('', app.routeData_.page); assertEquals('history', app.selectedPage_);
assertEquals('chrome://history/', window.location.href); assertEquals('chrome://history/', window.location.href);
MockInteractions.tap(menu.children[1]); MockInteractions.tap(menu.children[1]);
assertEquals('syncedTabs', app.routeData_.page); assertEquals('syncedTabs', app.selectedPage_);
assertEquals('chrome://history/syncedTabs', window.location.href); assertEquals('chrome://history/syncedTabs', window.location.href);
MockInteractions.keyDownOn(menu.children[0], 32, '', "Space"); MockInteractions.keyDownOn(menu.children[0], 32, '', "Space");
assertEquals('', app.routeData_.page); assertEquals('history', app.selectedPage_);
assertEquals('chrome://history/', window.location.href); assertEquals('chrome://history/', window.location.href);
}); });
test('route updates from search', function() {
var searchTerm = 'McCree';
assertEquals('', app.routeData_.page);
toolbar.setSearchTerm(searchTerm);
assertEquals(searchTerm, app.queryParams_.q);
});
test('search updates from route', function() { test('search updates from route', function() {
assertEquals('chrome://history/', window.location.href);
var searchTerm = 'Mei'; var searchTerm = 'Mei';
assertEquals('history', app.$.content.selected); assertEquals('history', app.$.content.selected);
app.set('queryParams_.q', searchTerm); navigateTo('/?q=' + searchTerm);
assertEquals(searchTerm, toolbar.searchTerm); assertEquals(searchTerm, toolbar.searchTerm);
}); });
test('route updates from search', function() {
var searchTerm = 'McCree';
assertEquals('history', app.$.content.selected);
app.set('queryState_.searchTerm', searchTerm);
assertEquals('chrome://history/?q=' + searchTerm, window.location.href);
});
test('search preserved across menu items', function() { test('search preserved across menu items', function() {
var searchTerm = 'Soldier 76'; var searchTerm = 'Soldier76';
var menu = sidebar.$.menu; var menu = sidebar.$.menu;
assertEquals('', app.routeData_.page); assertEquals('history', app.selectedPage_);
assertEquals('history', app.$.content.selected); navigateTo('/?q=' + searchTerm);
app.set('queryParams_.q', searchTerm);
MockInteractions.tap(menu.children[1]); MockInteractions.tap(menu.children[1]);
assertEquals('syncedTabs', app.routeData_.page); assertEquals('syncedTabs', app.selectedPage_);
assertEquals(searchTerm, app.queryParams_.q);
assertEquals(searchTerm, toolbar.searchTerm); assertEquals(searchTerm, toolbar.searchTerm);
assertEquals(
'chrome://history/syncedTabs?q=' + searchTerm,
window.location.href);
MockInteractions.tap(menu.children[0]); MockInteractions.tap(menu.children[0]);
assertEquals('', app.routeData_.page); assertEquals('history', app.selectedPage_);
assertEquals(searchTerm, app.queryParams_.q);
assertEquals(searchTerm, toolbar.searchTerm); assertEquals(searchTerm, toolbar.searchTerm);
assertEquals('chrome://history/?q=' + searchTerm, window.location.href);
}); });
teardown(function() { teardown(function() {
app.set('routeData_.page', ''); // Reset back to initial navigation state.
app.set('queryParams_.q', null); navigateTo('/');
}); });
}); });
} }
......
...@@ -22,6 +22,8 @@ class UnusedElementsDetector(object): ...@@ -22,6 +22,8 @@ class UnusedElementsDetector(object):
__WHITELIST = ( __WHITELIST = (
# Necessary for closure. # Necessary for closure.
'polymer-externs', 'polymer-externs',
# TODO(tsergeant): Remove app-route from Chromium.
'app-route',
) )
def __init__(self): def __init__(self):
......
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