diff options
author | csilv@chromium.org <csilv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-09 18:54:54 +0000 |
---|---|---|
committer | csilv@chromium.org <csilv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-09 18:54:54 +0000 |
commit | 829ddb955ec68f169f1dcd24af6d90f58307e8b7 (patch) | |
tree | aab8599bd73b4f54645700bca915c9e525ef4cfe /chrome/browser/resources | |
parent | 32e1dee439ca0946f80508eeeedaebfbc2cc907c (diff) | |
download | chromium_src-829ddb955ec68f169f1dcd24af6d90f58307e8b7.zip chromium_src-829ddb955ec68f169f1dcd24af6d90f58307e8b7.tar.gz chromium_src-829ddb955ec68f169f1dcd24af6d90f58307e8b7.tar.bz2 |
webui settings:
- Add basic highlighting for search results.
- Allow partial page title search matches.
BUG=59267
TEST=Perform searches in the webui settings window.
Review URL: http://codereview.chromium.org/5562011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68751 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resources')
-rw-r--r-- | chrome/browser/resources/options/search_page.css | 4 | ||||
-rw-r--r-- | chrome/browser/resources/options/search_page.js | 127 |
2 files changed, 92 insertions, 39 deletions
diff --git a/chrome/browser/resources/options/search_page.css b/chrome/browser/resources/options/search_page.css index 03a775e..e5e44d6 100644 --- a/chrome/browser/resources/options/search_page.css +++ b/chrome/browser/resources/options/search_page.css @@ -1,3 +1,7 @@ .search-hidden { display: none; } + +.search-highlighted { + background-color: #fff29f; +} diff --git a/chrome/browser/resources/options/search_page.js b/chrome/browser/resources/options/search_page.js index feec95a..5e76496 100644 --- a/chrome/browser/resources/options/search_page.js +++ b/chrome/browser/resources/options/search_page.js @@ -92,14 +92,19 @@ cr.define('options', function() { } var page, length, childDiv; - for (var name in OptionsPage.registeredPages) { - if (name == this.name) - continue; + var pagesToSearch = this.getSearchablePages_(); + for (var key in pagesToSearch) { + var page = pagesToSearch[key]; + + if (!active) { + page.visible = false; + this.unhighlightMatches_(page.tab); + this.unhighlightMatches_(page.pageDiv); + } // Update the visible state of all top-level elements that are not // sections (ie titles, button strips). We do this before changing // the page visibility to avoid excessive re-draw. - page = OptionsPage.registeredPages[name]; length = page.pageDiv.childNodes.length; for (var i = 0; i < length; i++) { childDiv = page.pageDiv.childNodes[i]; @@ -108,7 +113,7 @@ cr.define('options', function() { if (childDiv.nodeName.toLowerCase() != 'section') childDiv.classList.add('search-hidden'); } else { - childDiv.classList.remove('search-hidden'); + childDiv.classList.remove('search-hidden'); } } } @@ -118,8 +123,6 @@ cr.define('options', function() { // When search is active, remove the 'hidden' tag. This tag may have // been added by the OptionsPage. page.pageDiv.classList.remove('hidden'); - } else { - page.visible = false; } } }, @@ -130,29 +133,43 @@ cr.define('options', function() { * @private */ setSearchText_: function(text) { - var searchText = text.toLowerCase(); var foundMatches = false; - // Build a list of pages to search. Omit the search page. - var pagesToSearch = []; - for (var name in OptionsPage.registeredPages) { - if (name != this.name) - pagesToSearch.push(OptionsPage.registeredPages[name]); - } + // Generate search text by applying lowercase and escaping any characters + // that would be problematic for regular expressions. + var searchText = + text.toLowerCase().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + + // Generate a regular expression and transform string for searching the + // navigation sidebar. + var navRegEx = new RegExp('(\\b' + searchText + ')', 'ig'); + var navTransform = '<span class="search-highlighted">$1</span>'; - // Hide all sections. If the search string matches a title page, show - // all sections of that page. + // Generate a regular expression and transform string for searching the + // pages. + var sectionRegEx = + new RegExp('>([^<]*)?(\\b' + searchText + ')([^>]*)?<', 'ig'); + var sectionTransform = '>$1<span class="search-highlighted">$2</span>$3<'; + + // Initialize all sections. If the search string matches a title page, + // show sections for that page. + var pagesToSearch = this.getSearchablePages_(); for (var key in pagesToSearch) { var page = pagesToSearch[key]; - var pageTitle = page.title.toLowerCase(); - // Hide non-sections in each page. + this.unhighlightMatches_(page.tab); + this.unhighlightMatches_(page.pageDiv); + var pageMatch = false; + if (searchText.length) { + pageMatch = this.performReplace_(navRegEx, navTransform, page.tab); + } + if (pageMatch) + foundMatches = true; for (var i = 0; i < page.pageDiv.childNodes.length; i++) { var childDiv = page.pageDiv.childNodes[i]; if (childDiv.nodeType == 1 && childDiv.nodeName.toLowerCase() == 'section') { - if (pageTitle == searchText) { + if (pageMatch) { childDiv.classList.remove('search-hidden'); - foundMatches = true; } else { childDiv.classList.add('search-hidden'); } @@ -160,30 +177,18 @@ cr.define('options', function() { } } - // Now search all sections for anchored string matches. - if (!foundMatches && searchText.length) { - var searchRegEx = new RegExp('\\b' + searchText, 'i'); + // Search all sections for anchored string matches. + if (searchText.length) { for (var key in pagesToSearch) { var page = pagesToSearch[key]; for (var i = 0; i < page.pageDiv.childNodes.length; i++) { var childDiv = page.pageDiv.childNodes[i]; if (childDiv.nodeType == 1 && - childDiv.nodeName.toLowerCase() == 'section') { - var isMatch = false; - var sectionElements = childDiv.getElementsByTagName("*"); - var length = sectionElements.length; - var element; - for (var j = 0; j < length; j++) { - element = sectionElements[j]; - if (searchRegEx.test(element.textContent)) { - isMatch = true; - break; - } - } - if (isMatch) { - childDiv.classList.remove('search-hidden'); - foundMatches = true; - } + childDiv.nodeName.toLowerCase() == 'section' && + this.performReplace_(sectionRegEx, sectionTransform, + childDiv)) { + childDiv.classList.remove('search-hidden'); + foundMatches = true; } } } @@ -200,6 +205,50 @@ cr.define('options', function() { $('searchPageInfo').classList.add('search-hidden'); $('searchPageNoMatches').classList.remove('search-hidden'); } + }, + + /** + * Performs a string replacement based on a regex and transform. + * @param {RegEx} regex A regular expression for finding search matches. + * @param {String} transform A string to apply the replace operation. + * @param {Element} element An HTML container element. + * @returns {Boolean} true if the element was changed. + * @private + */ + performReplace_: function(regex, transform, element) { + var originalHTML = element.innerHTML; + var newHTML = originalHTML.replace(regex, transform); + if (originalHTML != newHTML) { + element.innerHTML = newHTML; + return true; + } else { + return false; + } + }, + + /** + * Removes all search highlight tags from a container element. + * @param {Element} element An HTML container element. + * @private + */ + unhighlightMatches_: function(element) { + var regex = + new RegExp('<span class="search-highlighted">(.*?)</span>', 'g'); + element.innerHTML = element.innerHTML.replace(regex, '$1'); + }, + + /** + * Builds a list of pages to search. Omits the search page. + * @returns {Array} An array of pages to search. + * @private + */ + getSearchablePages_: function() { + var pages = []; + for (var name in OptionsPage.registeredPages) { + if (name != this.name) + pages.push(OptionsPage.registeredPages[name]); + } + return pages; } }; |