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

Unified Diff: chrome/browser/resources/settings/search_settings.js

Issue 2176743004: MD Settings: Implementing a "no results" page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comment. Created 4 years, 5 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/settings/search_settings.js
diff --git a/chrome/browser/resources/settings/search_settings.js b/chrome/browser/resources/settings/search_settings.js
index 03f1062dc6533fc2e08f783b7cf298e153b8b760..f001427a140d760bf52ada4df340c8a092609fb8 100644
--- a/chrome/browser/resources/settings/search_settings.js
+++ b/chrome/browser/resources/settings/search_settings.js
@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-/** @typedef {{id: number, rawQuery: ?string, regExp: ?RegExp}} */
-var SearchContext;
-
cr.define('settings', function() {
/** @const {string} */
var WRAPPER_CSS_CLASS = 'search-highlight-wrapper';
@@ -103,16 +100,17 @@ cr.define('settings', function() {
* ensures that <settings-section> instances become visible if any matches
* occurred under their subtree.
*
- * @param {!SearchContext} context
+ * @param {!SearchRequest} request
* @param {!Node} root The root of the sub-tree to be searched
* @private
*/
- function findAndHighlightMatches_(context, root) {
+ function findAndHighlightMatches_(request, root) {
+ var foundMatches = false;
function doSearch(node) {
if (node.nodeName == 'TEMPLATE' && node.hasAttribute('name') &&
!node.if) {
getSearchManager().queue_.addRenderTask(
- new RenderTask(context, node));
+ new RenderTask(request, node));
return;
}
@@ -124,9 +122,10 @@ cr.define('settings', function() {
if (textContent.length == 0)
return;
- if (context.regExp.test(textContent)) {
+ if (request.regExp.test(textContent)) {
+ foundMatches = true;
revealParentSection_(node);
- highlight_(node, textContent.split(context.regExp));
+ highlight_(node, textContent.split(request.regExp));
}
// Returning early since TEXT_NODE nodes never have children.
return;
@@ -147,6 +146,7 @@ cr.define('settings', function() {
}
doSearch(root);
+ return foundMatches;
}
/**
@@ -167,12 +167,12 @@ cr.define('settings', function() {
/**
* @constructor
*
- * @param {!SearchContext} context
+ * @param {!SearchRequest} request
* @param {!Node} node
*/
- function Task(context, node) {
- /** @protected {!SearchContext} */
- this.context = context;
+ function Task(request, node) {
+ /** @protected {!SearchRequest} */
+ this.request = request;
/** @protected {!Node} */
this.node = node;
@@ -193,11 +193,11 @@ cr.define('settings', function() {
* @constructor
* @extends {Task}
*
- * @param {!SearchContext} context
+ * @param {!SearchRequest} request
* @param {!Node} node
*/
- function RenderTask(context, node) {
- Task.call(this, context, node);
+ function RenderTask(request, node) {
+ Task.call(this, request, node);
}
RenderTask.prototype = {
@@ -216,7 +216,7 @@ cr.define('settings', function() {
// Register a SearchAndHighlightTask for the part of the DOM that was
// just rendered.
getSearchManager().queue_.addSearchAndHighlightTask(
- new SearchAndHighlightTask(this.context, assert(renderedNode)));
+ new SearchAndHighlightTask(this.request, assert(renderedNode)));
resolve();
}.bind(this));
}.bind(this));
@@ -227,17 +227,18 @@ cr.define('settings', function() {
* @constructor
* @extends {Task}
*
- * @param {!SearchContext} context
+ * @param {!SearchRequest} request
* @param {!Node} node
*/
- function SearchAndHighlightTask(context, node) {
- Task.call(this, context, node);
+ function SearchAndHighlightTask(request, node) {
+ Task.call(this, request, node);
}
SearchAndHighlightTask.prototype = {
/** @override */
exec: function() {
- findAndHighlightMatches_(this.context, this.node);
+ var foundMatches = findAndHighlightMatches_(this.request, this.node);
+ this.request.updateMatches(foundMatches);
return Promise.resolve();
},
};
@@ -246,11 +247,11 @@ cr.define('settings', function() {
* @constructor
* @extends {Task}
*
- * @param {!SearchContext} context
+ * @param {!SearchRequest} request
* @param {!Node} page
*/
- function TopLevelSearchTask(context, page) {
- Task.call(this, context, page);
+ function TopLevelSearchTask(request, page) {
+ Task.call(this, request, page);
}
TopLevelSearchTask.prototype = {
@@ -258,10 +259,12 @@ cr.define('settings', function() {
exec: function() {
findAndRemoveHighlights_(this.node);
- var shouldSearch = this.context.regExp !== null;
+ var shouldSearch = this.request.regExp !== null;
this.setSectionsVisibility_(!shouldSearch);
- if (shouldSearch)
- findAndHighlightMatches_(this.context, this.node);
+ if (shouldSearch) {
+ var foundMatches = findAndHighlightMatches_(this.request, this.node);
+ this.request.updateMatches(foundMatches);
+ }
return Promise.resolve();
},
@@ -292,6 +295,9 @@ cr.define('settings', function() {
this.queues_;
this.reset();
+ /** @private {?Function} */
+ this.onEmptyCallback_ = null;
+
/**
* Whether a task is currently running.
* @private {boolean}
@@ -324,6 +330,14 @@ cr.define('settings', function() {
},
/**
+ * Registers a callback to be called every time the queue becomes empty.
+ * @param {function():void} onEmptyCallback
+ */
+ onEmpty: function(onEmptyCallback) {
+ this.onEmptyCallback_ = onEmptyCallback;
+ },
+
+ /**
* @return {!Task|undefined}
* @private
*/
@@ -342,7 +356,8 @@ cr.define('settings', function() {
var task = this.popNextTask_();
if (!task) {
this.running_ = false;
- getSearchManager().notifyCallback(false);
+ if (this.onEmptyCallback_)
+ this.onEmptyCallback_();
return;
}
@@ -352,8 +367,8 @@ cr.define('settings', function() {
this.running_ = false;
this.consumePending_();
}
- if (task.context.id ==
- getSearchManager().activeContext_.id) {
+ if (task.request.id ==
+ getSearchManager().activeRequest_.id) {
task.exec().then(startNextTask.bind(this));
} else {
// Dropping this task without ever executing it, since a new search
@@ -369,63 +384,116 @@ cr.define('settings', function() {
/**
* @constructor
*/
- var SearchManager = function() {
- /** @private {!TaskQueue} */
- this.queue_ = new TaskQueue();
+ var SearchRequest = function(rawQuery) {
+ /** @type {number} */
+ this.id = SearchRequest.nextId_++;
+
+ /** @private {string} */
+ this.rawQuery_ = rawQuery;
- /** @private {!SearchContext} */
- this.activeContext_ = {id: 0, rawQuery: null, regExp: null};
+ /** @type {?RegExp} */
+ this.regExp = this.generateRegExp_();
- /** @private {?function(boolean):void} */
- this.callbackFn_ = null;
+ /**
+ * Whether this request was fully processed.
+ * @type {boolean}
+ */
+ this.finished = false;
+
+ /** @private {boolean} */
+ this.foundMatches_ = false;
+
+ /** @type {!PromiseResolver} */
+ this.resolver = new PromiseResolver();
};
- cr.addSingletonGetter(SearchManager);
- /** @private @const {!RegExp} */
- SearchManager.SANITIZE_REGEX_ = /[-[\]{}()*+?.,\\^$|#\s]/g;
+ /** @private {number} */
+ SearchRequest.nextId_ = 0;
+
+ /** @private {!RegExp} */
+ SearchRequest.SANITIZE_REGEX_ = /[-[\]{}()*+?.,\\^$|#\s]/g;
+
+ SearchRequest.prototype = {
+ /**
+ * @return {?RegExp}
+ * @private
+ */
+ generateRegExp_: function() {
+ var regExp = null;
+
+ // Generate search text by escaping any characters that would be
+ // problematic for regular expressions.
+ var searchText = this.rawQuery_.trim().replace(
+ SearchRequest.SANITIZE_REGEX_, '\\$&');
+ if (searchText.length > 0)
+ regExp = new RegExp('(' + searchText + ')', 'i');
+
+ return regExp;
+ },
+
+ /**
+ * @param {string} rawQuery
+ * @return {boolean} Whether this SearchRequest refers to an identical
+ * query.
+ */
+ isSame: function(rawQuery) {
+ return this.rawQuery_ == rawQuery;
+ },
- SearchManager.prototype = {
/**
- * Registers a callback function that will be called every time search
- * starts/finishes.
- * @param {?function(boolean):void} callbackFn
+ * Updates the result for this search request.
+ * @param {boolean} found
*/
- setCallback: function(callbackFn) {
- this.callbackFn_ = callbackFn;
+ updateMatches: function(found) {
+ this.foundMatches_ = this.foundMatches_ || found;
},
- /** @param {boolean} isRunning */
- notifyCallback: function(isRunning) {
- if (this.callbackFn_)
- this.callbackFn_(isRunning);
+ /** @return {boolean} Whether any matches were found. */
+ didFindMatches: function() {
+ return this.foundMatches_;
},
+ };
+
+ /**
+ * @constructor
+ */
+ var SearchManager = function() {
+ /** @private {?SearchRequest} */
+ this.activeRequest_ = null;
+ /** @private {!TaskQueue} */
+ this.queue_ = new TaskQueue();
+ this.queue_.onEmpty(function() {
+ this.activeRequest_.finished = true;
+ this.activeRequest_.resolver.resolve(this.activeRequest_);
+ this.activeRequest_ = null;
+ }.bind(this));
+ };
+ cr.addSingletonGetter(SearchManager);
+
+ SearchManager.prototype = {
/**
* @param {string} text The text to search for.
* @param {!Node} page
+ * @return {!Promise<!SearchRequest>} A signal indicating that searching
+ * finished.
*/
search: function(text, page) {
- if (this.activeContext_.rawQuery != text) {
- var newId = this.activeContext_.id + 1;
-
- var regExp = null;
- // Generate search text by escaping any characters that would be
- // problematic for regular expressions.
- var searchText = text.trim().replace(
- SearchManager.SANITIZE_REGEX_, '\\$&');
- if (searchText.length > 0)
- regExp = new RegExp('(' + searchText + ')', 'i');
-
- this.activeContext_ = {id: newId, rawQuery: text, regExp: regExp};
-
- // Drop all previously scheduled tasks, since a new search was just
- // issued.
+ // Creating a new request only if the |text| changed.
+ if (!this.activeRequest_ || !this.activeRequest_.isSame(text)) {
+ // Resolving previous search request without marking it as
+ // 'finisthed', if any, and droping all pending tasks.
this.queue_.reset();
- this.notifyCallback(true);
+ if (this.activeRequest_)
+ this.activeRequest_.resolver.resolve(this.activeRequest_);
+
+ this.activeRequest_ = new SearchRequest(text);
}
this.queue_.addTopLevelSearchTask(
- new TopLevelSearchTask(this.activeContext_, page));
+ new TopLevelSearchTask(this.activeRequest_, page));
+
+ return this.activeRequest_.resolver.promise;
},
};
« no previous file with comments | « chrome/app/settings_strings.grdp ('k') | chrome/browser/resources/settings/settings_main/settings_main.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698