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

Side by Side Diff: chrome/browser/resources/settings/search_settings.js

Issue 1952493002: MD Settings: Proof of concept, highlighting search matches across Shadow DOM boundaries. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/resources/settings/settings_resources.grd » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 (function() {
6 var WRAPPER_CSS_CLASS = 'search-highlight-wrapper';
7 var HIT_CSS_CLASS = 'search-highlight-hit';
8
9 function findChildren_(element) {
10 var children = [];
11 var walker = document.createTreeWalker(
12 element.shadowRoot, NodeFilter.SHOW_ELEMENTS, null, false);
13 var node = walker.nextNode();
14 while (node) {
15 if (!!node.shadowRoot)
16 children.push(node);
17
18 node = walker.nextNode();
19 }
20 return children;
21 }
22
23 /**
24 * Highlights all matches in the given element. Ignores children that have
25 * their own Shadow DOW.
26 * @param {!RegExp} regexp
27 * @param {!Element} element
28 * @return {boolean} Whether any matches were found.
29 */
30 function highlightSelfMatches_(regExp, element) {
31 var found = false;
32 var walker = document.createTreeWalker(
33 element.shadowRoot, NodeFilter.SHOW_TEXT, null, false);
34
35 var node = walker.nextNode();
36 while (node) {
37 var textContent = node.nodeValue;
38 var tokens = textContent.split(regExp);
39
40 if (node.parentNode.tagName == 'STYLE' || tokens.length == 1) {
41 node = walker.nextNode();
42 continue;
43 }
44
45 var nextNode = walker.nextNode();
46 var parentNode = node.parentNode;
47 // Use existing node as placeholder to determine where to insert the
48 // replacement content.
49
50 var wrapper = document.createElement('span');
51 wrapper.classList.add(WRAPPER_CSS_CLASS);
52 parentNode.insertBefore(wrapper, node);
53
54 for (var i = 0; i < tokens.length; ++i) {
55 if (i % 2 == 0) {
56 wrapper.appendChild(document.createTextNode(tokens[i]));
57 } else {
58 fount = true;
59 var span = document.createElement('span');
60 span.classList.add(HIT_CSS_CLASS);
61 span.style['background-color'] = 'yellow';
62 span.textContent = tokens[i];
63 wrapper.appendChild(span);
64 }
65 }
66
67 // Remove old node.
68 node.remove();
69 node = nextNode;
70 }
71
72 return found;
73 }
74
75 /**
76 * Un-highlights all previous matches in the given element. It ignores
77 * children that have their own Shadow DOM.
78 * @param {!Element} element
79 */
80 function unhighlightSelfMatches_(element) {
81 var wrappers = element.shadowRoot.querySelectorAll('.' + WRAPPER_CSS_CLASS);
82 wrappers.forEach(function(wrapper) {
83 wrapperParent = wrapper.parentElement;
84 var elements = wrapper.querySelectorAll('.' + HIT_CSS_CLASS);
85 // For each element, remove the highlighting.
86 for (var i = 0; i < elements.length; i++) {
87 var node = elements[i];
88 wrapper.replaceChild(node.firstChild, node);
89 }
90
91 // Normalize so that adjacent text nodes will be combined.
92 wrapper.normalize();
93 // Restore the DOM structure as it was before the search occurred.
94 wrapperParent.appendChild(wrapper.firstChild);
95 wrapper.remove();
96 });
97 }
98
99 /**
100 * Highlights all matches (both within self and children's Shadow DOM).
101 * @param {!RegExp} regexp
102 * @param {!Element} element
103 */
104 function highlightMatches_(regexp, element) {
105 highlightSelfMatches_(regexp, element);
106 findChildren_(element).forEach(function(child) {
107 highlightMatches_(regexp, child);
108 });
109 }
110
111 /**
112 * Un-highlights all previous matches (both within self and children's Shadow
113 * DOM).
114 * @param {!Element} element
115 */
116 function unhighlightMatches_(element) {
117 unhighlightSelfMatches_(element);
118 findChildren_(element).forEach(unhighlightMatches_);
119 }
120
121 /**
122 * Performs hierarchical search, starting at the given element.
123 * @param {string} text
124 * @param {!Element} element
125 */
126 function search(text, element) {
127 unhighlightMatches_(element);
128
129 var searchText =
130 text.trim().toLowerCase().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
131 if (searchText.length == 0) {
132 return;
133 }
134
135 highlightMatches_(new RegExp('(' + searchText + ')', 'ig'), element);
136 }
137
138 window.search = search;
139 })();
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/settings/settings_resources.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698