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

Unified Diff: chrome/browser/resources/md_extensions/navigation_helper.js

Issue 2811993004: [MD Extensions] Add support for URL navigation (Closed)
Patch Set: Michael's Created 3 years, 8 months 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_extensions/navigation_helper.js
diff --git a/chrome/browser/resources/md_extensions/navigation_helper.js b/chrome/browser/resources/md_extensions/navigation_helper.js
new file mode 100644
index 0000000000000000000000000000000000000000..d22e9a7d89616bd427aa72037f5c9a45fd2db06d
--- /dev/null
+++ b/chrome/browser/resources/md_extensions/navigation_helper.js
@@ -0,0 +1,116 @@
+// Copyright 2017 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.
+
+/**
+ * The different pages that can be shown at a time.
+ * Note: This must remain in sync with the order in manager.html!
michaelpg 2017/05/01 23:41:25 with the page ids
Devlin 2017/05/02 01:04:07 Done.
+ * @enum {string}
+ */
+var Page = {
+ LIST: 'items-list',
+ DETAILS: 'details-view',
+ SHORTCUTS: 'keyboard-shortcuts',
+ ERRORS: 'error-page',
+};
+
+/** @enum {string} */
+var Dialog = {
+ OPTIONS: 'options',
+};
+
+/** @typedef {{page: Page,
+ id: (string|undefined),
michaelpg 2017/05/01 23:41:25 You probably have this problem all throughout exte
Devlin 2017/05/02 01:04:07 done.
+ subpage: (!Dialog|undefined)}} */
+var PageState;
+
+cr.define('extensions', function() {
+ 'use strict';
+
+ /**
+ * A helper object to manage in-page navigations. Since the extensions page
+ * needs to support different urls for different subpages (like the details
+ * page), we use this object to manage the history and url conversions.
+ * @param {!function(!PageState):void} onHistoryChange A function to call when
+ * the page has changed as a result of the user going back or forward in
+ * history; called with the new active page.
+ * @constructor */
+ function NavigationHelper(onHistoryChange) {
+ this.onHistoryChange_ = onHistoryChange;
+ window.addEventListener('popstate', this.onPopState_.bind(this));
+ }
+
+ NavigationHelper.prototype = {
+ /** @private */
+ onPopState_: function() {
+ this.onHistoryChange_(this.getCurrentPage());
+ },
+
+ /**
+ * Returns the page that should be displayed for the current URL.
+ * @return {!PageState}
+ */
+ getCurrentPage: function() {
+ if (location.search == '' && location.pathname == '/')
michaelpg 2017/05/01 23:41:25 i'd be in favor of removing this, as it's already
Devlin 2017/05/02 01:04:07 Done.
+ return {page: Page.LIST};
+
+ var search = new URLSearchParams(location.search);
+ var id = search.get('id');
+ if (id)
+ return {page: Page.DETAILS, id: id};
+ id = search.get('options');
+ if (id)
+ return {page: Page.DETAILS, id: id, subpage: Dialog.OPTIONS};
+ id = search.get('errors');
+ if (id)
+ return {page: Page.ERRORS, id: id};
+
+ if (location.pathname == '/shortcuts')
+ return {page: Page.SHORTCUTS};
+
+ return {page: Page.LIST};
+ },
+
+ /**
+ * Called when a page changes, and pushes state to history to reflect it.
+ * @param {!PageState} entry
+ */
+ updateHistory: function(entry) {
+ var relative;
michaelpg 2017/05/01 23:41:25 absolute? :-\
Devlin 2017/05/02 01:04:07 s/relative/path
+ switch (entry.page) {
+ case Page.LIST:
+ relative = '/';
+ break;
+ case Page.DETAILS:
+ if (entry.subpage) {
+ assert(entry.subpage == Dialog.OPTIONS);
+ relative = '/?options=' + entry.id;
+ } else {
+ relative = '/?id=' + entry.id;
+ }
+ break;
+ case Page.SHORTCUTS:
+ relative = '/shortcuts';
+ break;
+ case Page.ERRORS:
+ relative = '/?errors=' + entry.id;
michaelpg 2017/05/01 23:41:25 add a break; so adding another case doesn't cause
Devlin 2017/05/02 01:04:07 Done.
+ }
+ assert(relative);
+ var state = {url: relative};
+ var currentPage = this.getCurrentPage();
+ var isDialogNavigation =
+ currentPage.page == entry.page &&
+ currentPage.id == entry.id;
+ // Navigating to a dialog doesn't visually change pages; it just opens
+ // a dialog. As such, we replace state rather than pushing a new state
+ // on the stack so that hitting the back button doesn't just toggle the
+ // dialog.
+ if (isDialogNavigation)
+ history.replaceState(state, '', relative);
+ else
+ history.pushState(state, '', relative);
+ },
+ };
+
+ return {NavigationHelper: NavigationHelper};
+});

Powered by Google App Engine
This is Rietveld 408576698