Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** @typedef {{id: number, rawQuery: ?string, regExp: ?RegExp}} */ | 5 /** @typedef {{id: number, rawQuery: ?string, regExp: ?RegExp}} */ |
| 6 var SearchContext; | 6 var SearchContext; |
| 7 | 7 |
| 8 cr.define('settings', function() { | 8 cr.define('settings', function() { |
| 9 /** @const {string} */ | 9 /** @const {string} */ |
| 10 var WRAPPER_CSS_CLASS = 'search-highlight-wrapper'; | 10 var WRAPPER_CSS_CLASS = 'search-highlight-wrapper'; |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 subpageTemplate.id = subpageTemplate.id || this.node.getAttribute('name'); | 224 subpageTemplate.id = subpageTemplate.id || this.node.getAttribute('name'); |
| 225 assert(!this.node.if); | 225 assert(!this.node.if); |
| 226 this.node.if = true; | 226 this.node.if = true; |
| 227 | 227 |
| 228 return new Promise(function(resolve, reject) { | 228 return new Promise(function(resolve, reject) { |
| 229 var parent = this.node.parentNode; | 229 var parent = this.node.parentNode; |
| 230 parent.async(function() { | 230 parent.async(function() { |
| 231 var renderedNode = parent.querySelector('#' + subpageTemplate.id); | 231 var renderedNode = parent.querySelector('#' + subpageTemplate.id); |
| 232 // Register a SearchAndHighlightTask for the part of the DOM that was | 232 // Register a SearchAndHighlightTask for the part of the DOM that was |
| 233 // just rendered. | 233 // just rendered. |
| 234 SearchManager.getInstance().queue_.addSearchAndHighlightTask( | 234 SearchManager.getInstance().queue_.addSearchAndHighlightTask( |
|
Dan Beam
2016/07/19 00:06:26
nit: can we re-use getSearchManager() in other pla
dpapad
2016/07/19 00:36:42
Done.
| |
| 235 new SearchAndHighlightTask(this.context, assert(renderedNode))); | 235 new SearchAndHighlightTask(this.context, assert(renderedNode))); |
| 236 resolve(); | 236 resolve(); |
| 237 }.bind(this)); | 237 }.bind(this)); |
| 238 }.bind(this)); | 238 }.bind(this)); |
| 239 }, | 239 }, |
| 240 }; | 240 }; |
| 241 | 241 |
| 242 /** | 242 /** |
| 243 * @constructor | 243 * @constructor |
| 244 * @extends {Task} | 244 * @extends {Task} |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 | 351 |
| 352 /** @private */ | 352 /** @private */ |
| 353 consumePending_: function() { | 353 consumePending_: function() { |
| 354 if (this.running_) | 354 if (this.running_) |
| 355 return; | 355 return; |
| 356 | 356 |
| 357 while (1) { | 357 while (1) { |
| 358 var task = this.popNextTask_(); | 358 var task = this.popNextTask_(); |
| 359 if (!task) { | 359 if (!task) { |
| 360 this.running_ = false; | 360 this.running_ = false; |
| 361 getSearchManager().notifyCallback(false); | |
| 361 return; | 362 return; |
| 362 } | 363 } |
| 363 | 364 |
| 365 this.running_ = true; | |
| 364 window.requestIdleCallback(function() { | 366 window.requestIdleCallback(function() { |
| 365 function startNextTask() { | 367 function startNextTask() { |
| 366 this.running_ = false; | 368 this.running_ = false; |
| 367 this.consumePending_(); | 369 this.consumePending_(); |
| 368 } | 370 } |
| 369 if (task.context.id == | 371 if (task.context.id == |
| 370 SearchManager.getInstance().activeContext_.id) { | 372 SearchManager.getInstance().activeContext_.id) { |
| 371 task.exec().then(startNextTask.bind(this)); | 373 task.exec().then(startNextTask.bind(this)); |
| 372 } else { | 374 } else { |
| 373 // Dropping this task without ever executing it, since a new search | 375 // Dropping this task without ever executing it, since a new search |
| 374 // has been issued since this task was queued. | 376 // has been issued since this task was queued. |
| 375 startNextTask.call(this); | 377 startNextTask.call(this); |
| 376 } | 378 } |
| 377 }.bind(this)); | 379 }.bind(this)); |
| 378 return; | 380 return; |
| 379 } | 381 } |
| 380 }, | 382 }, |
| 381 }; | 383 }; |
| 382 | 384 |
| 383 /** | 385 /** |
| 384 * @constructor | 386 * @constructor |
| 385 */ | 387 */ |
| 386 var SearchManager = function() { | 388 var SearchManager = function() { |
| 387 /** @private {!TaskQueue} */ | 389 /** @private {!TaskQueue} */ |
| 388 this.queue_ = new TaskQueue(); | 390 this.queue_ = new TaskQueue(); |
| 389 | 391 |
| 390 /** @private {!SearchContext} */ | 392 /** @private {!SearchContext} */ |
| 391 this.activeContext_ = {id: 0, rawQuery: null, regExp: null}; | 393 this.activeContext_ = {id: 0, rawQuery: null, regExp: null}; |
| 394 | |
| 395 /** @private {?function(boolean):void} */ | |
| 396 this.callbackFn_ = null; | |
| 392 }; | 397 }; |
| 393 cr.addSingletonGetter(SearchManager); | 398 cr.addSingletonGetter(SearchManager); |
| 394 | 399 |
| 395 /** @private @const {!RegExp} */ | 400 /** @private @const {!RegExp} */ |
| 396 SearchManager.SANITIZE_REGEX_ = /[-[\]{}()*+?.,\\^$|#\s]/g; | 401 SearchManager.SANITIZE_REGEX_ = /[-[\]{}()*+?.,\\^$|#\s]/g; |
| 397 | 402 |
| 398 SearchManager.prototype = { | 403 SearchManager.prototype = { |
| 399 /** | 404 /** |
| 405 * Registers a callback function that will be called every time search | |
| 406 * starts/finishes. | |
| 407 * @param {?function(boolean):void} callbackFn | |
| 408 */ | |
| 409 setCallback: function(callbackFn) { | |
| 410 this.callbackFn_ = callbackFn; | |
| 411 }, | |
| 412 | |
| 413 /** @param {boolean} isRunning */ | |
| 414 notifyCallback: function(isRunning) { | |
| 415 if (this.callbackFn_) | |
| 416 this.callbackFn_(isRunning); | |
| 417 }, | |
| 418 | |
| 419 /** | |
| 400 * @param {string} text The text to search for. | 420 * @param {string} text The text to search for. |
| 401 * @param {!Node} page | 421 * @param {!Node} page |
| 402 */ | 422 */ |
| 403 search: function(text, page) { | 423 search: function(text, page) { |
| 404 if (this.activeContext_.rawQuery != text) { | 424 if (this.activeContext_.rawQuery != text) { |
| 405 var newId = this.activeContext_.id + 1; | 425 var newId = this.activeContext_.id + 1; |
| 406 | 426 |
| 407 var regExp = null; | 427 var regExp = null; |
| 408 // Generate search text by escaping any characters that would be | 428 // Generate search text by escaping any characters that would be |
| 409 // problematic for regular expressions. | 429 // problematic for regular expressions. |
| 410 var searchText = text.trim().replace( | 430 var searchText = text.trim().replace( |
| 411 SearchManager.SANITIZE_REGEX_, '\\$&'); | 431 SearchManager.SANITIZE_REGEX_, '\\$&'); |
| 412 if (searchText.length > 0) | 432 if (searchText.length > 0) |
| 413 regExp = new RegExp('(' + searchText + ')', 'i'); | 433 regExp = new RegExp('(' + searchText + ')', 'i'); |
| 414 | 434 |
| 415 this.activeContext_ = {id: newId, rawQuery: text, regExp: regExp}; | 435 this.activeContext_ = {id: newId, rawQuery: text, regExp: regExp}; |
| 416 | 436 |
| 417 // Drop all previously scheduled tasks, since a new search was just | 437 // Drop all previously scheduled tasks, since a new search was just |
| 418 // issued. | 438 // issued. |
| 419 this.queue_.reset(); | 439 this.queue_.reset(); |
| 440 this.notifyCallback(true); | |
| 420 } | 441 } |
| 421 | 442 |
| 422 this.queue_.addTopLevelSearchTask( | 443 this.queue_.addTopLevelSearchTask( |
| 423 new TopLevelSearchTask(this.activeContext_, page)); | 444 new TopLevelSearchTask(this.activeContext_, page)); |
| 424 }, | 445 }, |
| 425 }; | 446 }; |
| 426 | 447 |
| 427 /** | 448 /** @return {!SearchManager} */ |
| 428 * @param {string} text | 449 function getSearchManager() { |
| 429 * @param {!Node} page | 450 return SearchManager.getInstance(); |
| 430 */ | |
| 431 function search(text, page) { | |
| 432 SearchManager.getInstance().search(text, page); | |
| 433 } | 451 } |
| 434 | 452 |
| 435 return { | 453 return { |
| 436 search: search, | 454 getSearchManager: getSearchManager, |
| 437 }; | 455 }; |
| 438 }); | 456 }); |
| OLD | NEW |