| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3a25d0e814524420329eaf28b3196d11bb3f5357
|
| --- /dev/null
|
| +++ b/chrome/browser/resources/settings/search_settings.js
|
| @@ -0,0 +1,139 @@
|
| +// 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.
|
| +
|
| +(function() {
|
| + var WRAPPER_CSS_CLASS = 'search-highlight-wrapper';
|
| + var HIT_CSS_CLASS = 'search-highlight-hit';
|
| +
|
| + function findChildren_(element) {
|
| + var children = [];
|
| + var walker = document.createTreeWalker(
|
| + element.shadowRoot, NodeFilter.SHOW_ELEMENTS, null, false);
|
| + var node = walker.nextNode();
|
| + while (node) {
|
| + if (!!node.shadowRoot)
|
| + children.push(node);
|
| +
|
| + node = walker.nextNode();
|
| + }
|
| + return children;
|
| + }
|
| +
|
| + /**
|
| + * Highlights all matches in the given element. Ignores children that have
|
| + * their own Shadow DOW.
|
| + * @param {!RegExp} regexp
|
| + * @param {!Element} element
|
| + * @return {boolean} Whether any matches were found.
|
| + */
|
| + function highlightSelfMatches_(regExp, element) {
|
| + var found = false;
|
| + var walker = document.createTreeWalker(
|
| + element.shadowRoot, NodeFilter.SHOW_TEXT, null, false);
|
| +
|
| + var node = walker.nextNode();
|
| + while (node) {
|
| + var textContent = node.nodeValue;
|
| + var tokens = textContent.split(regExp);
|
| +
|
| + if (node.parentNode.tagName == 'STYLE' || tokens.length == 1) {
|
| + node = walker.nextNode();
|
| + continue;
|
| + }
|
| +
|
| + var nextNode = walker.nextNode();
|
| + var parentNode = node.parentNode;
|
| + // Use existing node as placeholder to determine where to insert the
|
| + // replacement content.
|
| +
|
| + var wrapper = document.createElement('span');
|
| + wrapper.classList.add(WRAPPER_CSS_CLASS);
|
| + parentNode.insertBefore(wrapper, node);
|
| +
|
| + for (var i = 0; i < tokens.length; ++i) {
|
| + if (i % 2 == 0) {
|
| + wrapper.appendChild(document.createTextNode(tokens[i]));
|
| + } else {
|
| + fount = true;
|
| + var span = document.createElement('span');
|
| + span.classList.add(HIT_CSS_CLASS);
|
| + span.style['background-color'] = 'yellow';
|
| + span.textContent = tokens[i];
|
| + wrapper.appendChild(span);
|
| + }
|
| + }
|
| +
|
| + // Remove old node.
|
| + node.remove();
|
| + node = nextNode;
|
| + }
|
| +
|
| + return found;
|
| + }
|
| +
|
| + /**
|
| + * Un-highlights all previous matches in the given element. It ignores
|
| + * children that have their own Shadow DOM.
|
| + * @param {!Element} element
|
| + */
|
| + function unhighlightSelfMatches_(element) {
|
| + var wrappers = element.shadowRoot.querySelectorAll('.' + WRAPPER_CSS_CLASS);
|
| + wrappers.forEach(function(wrapper) {
|
| + wrapperParent = wrapper.parentElement;
|
| + var elements = wrapper.querySelectorAll('.' + HIT_CSS_CLASS);
|
| + // For each element, remove the highlighting.
|
| + for (var i = 0; i < elements.length; i++) {
|
| + var node = elements[i];
|
| + wrapper.replaceChild(node.firstChild, node);
|
| + }
|
| +
|
| + // Normalize so that adjacent text nodes will be combined.
|
| + wrapper.normalize();
|
| + // Restore the DOM structure as it was before the search occurred.
|
| + wrapperParent.appendChild(wrapper.firstChild);
|
| + wrapper.remove();
|
| + });
|
| + }
|
| +
|
| + /**
|
| + * Highlights all matches (both within self and children's Shadow DOM).
|
| + * @param {!RegExp} regexp
|
| + * @param {!Element} element
|
| + */
|
| + function highlightMatches_(regexp, element) {
|
| + highlightSelfMatches_(regexp, element);
|
| + findChildren_(element).forEach(function(child) {
|
| + highlightMatches_(regexp, child);
|
| + });
|
| + }
|
| +
|
| + /**
|
| + * Un-highlights all previous matches (both within self and children's Shadow
|
| + * DOM).
|
| + * @param {!Element} element
|
| + */
|
| + function unhighlightMatches_(element) {
|
| + unhighlightSelfMatches_(element);
|
| + findChildren_(element).forEach(unhighlightMatches_);
|
| + }
|
| +
|
| + /**
|
| + * Performs hierarchical search, starting at the given element.
|
| + * @param {string} text
|
| + * @param {!Element} element
|
| + */
|
| + function search(text, element) {
|
| + unhighlightMatches_(element);
|
| +
|
| + var searchText =
|
| + text.trim().toLowerCase().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
| + if (searchText.length == 0) {
|
| + return;
|
| + }
|
| +
|
| + highlightMatches_(new RegExp('(' + searchText + ')', 'ig'), element);
|
| + }
|
| +
|
| + window.search = search;
|
| +})();
|
|
|