| 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 cr.exportPath('settings'); | 5 cr.exportPath('settings'); |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A data structure used by callers to combine the results of multiple search | 8 * A data structure used by callers to combine the results of multiple search |
| 9 * requests. | 9 * requests. |
| 10 * | 10 * |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 * Finds all previous highlighted nodes under |node| (both within self and | 60 * Finds all previous highlighted nodes under |node| (both within self and |
| 61 * children's Shadow DOM) and replaces the highlights (yellow rectangle and | 61 * children's Shadow DOM) and replaces the highlights (yellow rectangle and |
| 62 * search bubbles) with the original text node. | 62 * search bubbles) with the original text node. |
| 63 * TODO(dpapad): Consider making this a private method of TopLevelSearchTask. | 63 * TODO(dpapad): Consider making this a private method of TopLevelSearchTask. |
| 64 * @param {!Node} node | 64 * @param {!Node} node |
| 65 * @private | 65 * @private |
| 66 */ | 66 */ |
| 67 function findAndRemoveHighlights_(node) { | 67 function findAndRemoveHighlights_(node) { |
| 68 var wrappers = node.querySelectorAll('* /deep/ .' + WRAPPER_CSS_CLASS); | 68 var wrappers = node.querySelectorAll('* /deep/ .' + WRAPPER_CSS_CLASS); |
| 69 | 69 |
| 70 for (var i = 0; i < wrappers.length; i++ ) { | 70 for (var i = 0; i < wrappers.length; i++) { |
| 71 var wrapper = wrappers[i]; | 71 var wrapper = wrappers[i]; |
| 72 var originalNode = wrapper.querySelector( | 72 var originalNode = |
| 73 '.' + ORIGINAL_CONTENT_CSS_CLASS); | 73 wrapper.querySelector('.' + ORIGINAL_CONTENT_CSS_CLASS); |
| 74 wrapper.parentElement.replaceChild(originalNode.firstChild, wrapper); | 74 wrapper.parentElement.replaceChild(originalNode.firstChild, wrapper); |
| 75 } | 75 } |
| 76 | 76 |
| 77 var searchBubbles = node.querySelectorAll( | 77 var searchBubbles = |
| 78 '* /deep/ .' + SEARCH_BUBBLE_CSS_CLASS); | 78 node.querySelectorAll('* /deep/ .' + SEARCH_BUBBLE_CSS_CLASS); |
| 79 for (var j = 0; j < searchBubbles.length; j++) | 79 for (var j = 0; j < searchBubbles.length; j++) |
| 80 searchBubbles[j].remove(); | 80 searchBubbles[j].remove(); |
| 81 } | 81 } |
| 82 | 82 |
| 83 /** | 83 /** |
| 84 * Applies the highlight UI (yellow rectangle) around all matches in |node|. | 84 * Applies the highlight UI (yellow rectangle) around all matches in |node|. |
| 85 * @param {!Node} node The text node to be highlighted. |node| ends up | 85 * @param {!Node} node The text node to be highlighted. |node| ends up |
| 86 * being removed from the DOM tree. | 86 * being removed from the DOM tree. |
| 87 * @param {!Array<string>} tokens The string tokens after splitting on the | 87 * @param {!Array<string>} tokens The string tokens after splitting on the |
| 88 * relevant regExp. Even indices hold text that doesn't need highlighting, | 88 * relevant regExp. Even indices hold text that doesn't need highlighting, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 106 span.style.display = 'none'; | 106 span.style.display = 'none'; |
| 107 span.appendChild(node); | 107 span.appendChild(node); |
| 108 wrapper.appendChild(span); | 108 wrapper.appendChild(span); |
| 109 | 109 |
| 110 for (var i = 0; i < tokens.length; ++i) { | 110 for (var i = 0; i < tokens.length; ++i) { |
| 111 if (i % 2 == 0) { | 111 if (i % 2 == 0) { |
| 112 wrapper.appendChild(document.createTextNode(tokens[i])); | 112 wrapper.appendChild(document.createTextNode(tokens[i])); |
| 113 } else { | 113 } else { |
| 114 var span = document.createElement('span'); | 114 var span = document.createElement('span'); |
| 115 span.classList.add(HIT_CSS_CLASS); | 115 span.classList.add(HIT_CSS_CLASS); |
| 116 span.style.backgroundColor = '#ffeb3b'; // --var(--paper-yellow-500) | 116 span.style.backgroundColor = '#ffeb3b'; // --var(--paper-yellow-500) |
| 117 span.textContent = tokens[i]; | 117 span.textContent = tokens[i]; |
| 118 wrapper.appendChild(span); | 118 wrapper.appendChild(span); |
| 119 } | 119 } |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 | 122 |
| 123 /** | 123 /** |
| 124 * Traverses the entire DOM (including Shadow DOM), finds text nodes that | 124 * Traverses the entire DOM (including Shadow DOM), finds text nodes that |
| 125 * match the given regular expression and applies the highlight UI. It also | 125 * match the given regular expression and applies the highlight UI. It also |
| 126 * ensures that <settings-section> instances become visible if any matches | 126 * ensures that <settings-section> instances become visible if any matches |
| 127 * occurred under their subtree. | 127 * occurred under their subtree. |
| 128 * | 128 * |
| 129 * @param {!settings.SearchRequest} request | 129 * @param {!settings.SearchRequest} request |
| 130 * @param {!Node} root The root of the sub-tree to be searched | 130 * @param {!Node} root The root of the sub-tree to be searched |
| 131 * @private | 131 * @private |
| 132 */ | 132 */ |
| 133 function findAndHighlightMatches_(request, root) { | 133 function findAndHighlightMatches_(request, root) { |
| 134 var foundMatches = false; | 134 var foundMatches = false; |
| 135 function doSearch(node) { | 135 function doSearch(node) { |
| 136 if (node.nodeName == 'TEMPLATE' && node.hasAttribute('route-path') && | 136 if (node.nodeName == 'TEMPLATE' && node.hasAttribute('route-path') && |
| 137 !node.if && !node.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE)) { | 137 !node.if && !node.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE)) { |
| 138 request.queue_.addRenderTask(new RenderTask(request, node)); | 138 request.queue_.addRenderTask(new RenderTask(request, node)); |
| 139 return; | 139 return; |
| 140 } | 140 } |
| 141 | 141 |
| 142 if (IGNORED_ELEMENTS.has(node.nodeName)) | 142 if (IGNORED_ELEMENTS.has(node.nodeName)) |
| 143 return; | 143 return; |
| 144 | 144 |
| 145 if (node instanceof HTMLElement) { | 145 if (node instanceof HTMLElement) { |
| 146 var element = /** @type {HTMLElement} */(node); | 146 var element = /** @type {HTMLElement} */ (node); |
| 147 if (element.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE) || | 147 if (element.hasAttribute(SKIP_SEARCH_CSS_ATTRIBUTE) || |
| 148 element.hasAttribute('hidden') || | 148 element.hasAttribute('hidden') || element.style.display == 'none') { |
| 149 element.style.display == 'none') { | |
| 150 return; | 149 return; |
| 151 } | 150 } |
| 152 } | 151 } |
| 153 | 152 |
| 154 if (node.nodeType == Node.TEXT_NODE) { | 153 if (node.nodeType == Node.TEXT_NODE) { |
| 155 var textContent = node.nodeValue.trim(); | 154 var textContent = node.nodeValue.trim(); |
| 156 if (textContent.length == 0) | 155 if (textContent.length == 0) |
| 157 return; | 156 return; |
| 158 | 157 |
| 159 if (request.regExp.test(textContent)) { | 158 if (request.regExp.test(textContent)) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 * @param {!Node} node | 234 * @param {!Node} node |
| 236 * @param {string} rawQuery | 235 * @param {string} rawQuery |
| 237 * @private | 236 * @private |
| 238 */ | 237 */ |
| 239 function revealParentSection_(node, rawQuery) { | 238 function revealParentSection_(node, rawQuery) { |
| 240 var associatedControl = null; | 239 var associatedControl = null; |
| 241 // Find corresponding SETTINGS-SECTION parent and make it visible. | 240 // Find corresponding SETTINGS-SECTION parent and make it visible. |
| 242 var parent = node; | 241 var parent = node; |
| 243 while (parent && parent.nodeName !== 'SETTINGS-SECTION') { | 242 while (parent && parent.nodeName !== 'SETTINGS-SECTION') { |
| 244 parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? | 243 parent = parent.nodeType == Node.DOCUMENT_FRAGMENT_NODE ? |
| 245 parent.host : parent.parentNode; | 244 parent.host : |
| 245 parent.parentNode; |
| 246 if (parent.nodeName == 'SETTINGS-SUBPAGE') { | 246 if (parent.nodeName == 'SETTINGS-SUBPAGE') { |
| 247 // TODO(dpapad): Cast to SettingsSubpageElement here. | 247 // TODO(dpapad): Cast to SettingsSubpageElement here. |
| 248 associatedControl = assert( | 248 associatedControl = assert( |
| 249 parent.associatedControl, | 249 parent.associatedControl, |
| 250 'An associated control was expected for SETTINGS-SUBPAGE ' + | 250 'An associated control was expected for SETTINGS-SUBPAGE ' + |
| 251 parent.pageTitle + ', but was not found.'); | 251 parent.pageTitle + ', but was not found.'); |
| 252 } | 252 } |
| 253 } | 253 } |
| 254 if (parent) | 254 if (parent) |
| 255 parent.hiddenBySearch = false; | 255 parent.hiddenBySearch = false; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 */ | 437 */ |
| 438 onEmpty: function(onEmptyCallback) { | 438 onEmpty: function(onEmptyCallback) { |
| 439 this.onEmptyCallback_ = onEmptyCallback; | 439 this.onEmptyCallback_ = onEmptyCallback; |
| 440 }, | 440 }, |
| 441 | 441 |
| 442 /** | 442 /** |
| 443 * @return {!Task|undefined} | 443 * @return {!Task|undefined} |
| 444 * @private | 444 * @private |
| 445 */ | 445 */ |
| 446 popNextTask_: function() { | 446 popNextTask_: function() { |
| 447 return this.queues_.high.shift() || | 447 return this.queues_.high.shift() || this.queues_.middle.shift() || |
| 448 this.queues_.middle.shift() || | |
| 449 this.queues_.low.shift(); | 448 this.queues_.low.shift(); |
| 450 }, | 449 }, |
| 451 | 450 |
| 452 /** @private */ | 451 /** @private */ |
| 453 consumePending_: function() { | 452 consumePending_: function() { |
| 454 if (this.running_) | 453 if (this.running_) |
| 455 return; | 454 return; |
| 456 | 455 |
| 457 while (1) { | 456 while (1) { |
| 458 var task = this.popNextTask_(); | 457 var task = this.popNextTask_(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 | 527 |
| 529 /** | 528 /** |
| 530 * @return {?RegExp} | 529 * @return {?RegExp} |
| 531 * @private | 530 * @private |
| 532 */ | 531 */ |
| 533 generateRegExp_: function() { | 532 generateRegExp_: function() { |
| 534 var regExp = null; | 533 var regExp = null; |
| 535 | 534 |
| 536 // Generate search text by escaping any characters that would be | 535 // Generate search text by escaping any characters that would be |
| 537 // problematic for regular expressions. | 536 // problematic for regular expressions. |
| 538 var searchText = this.rawQuery_.trim().replace( | 537 var searchText = |
| 539 SearchRequest.SANITIZE_REGEX_, '\\$&'); | 538 this.rawQuery_.trim().replace(SearchRequest.SANITIZE_REGEX_, '\\$&'); |
| 540 if (searchText.length > 0) | 539 if (searchText.length > 0) |
| 541 regExp = new RegExp('(' + searchText + ')', 'i'); | 540 regExp = new RegExp('(' + searchText + ')', 'i'); |
| 542 | 541 |
| 543 return regExp; | 542 return regExp; |
| 544 }, | 543 }, |
| 545 | 544 |
| 546 /** | 545 /** |
| 547 * @param {string} rawQuery | 546 * @param {string} rawQuery |
| 548 * @return {boolean} Whether this SearchRequest refers to an identical | 547 * @return {boolean} Whether this SearchRequest refers to an identical |
| 549 * query. | 548 * query. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 function setSearchManagerForTesting(searchManager) { | 628 function setSearchManagerForTesting(searchManager) { |
| 630 SearchManagerImpl.instance_ = searchManager; | 629 SearchManagerImpl.instance_ = searchManager; |
| 631 } | 630 } |
| 632 | 631 |
| 633 return { | 632 return { |
| 634 getSearchManager: getSearchManager, | 633 getSearchManager: getSearchManager, |
| 635 setSearchManagerForTesting: setSearchManagerForTesting, | 634 setSearchManagerForTesting: setSearchManagerForTesting, |
| 636 SearchRequest: SearchRequest, | 635 SearchRequest: SearchRequest, |
| 637 }; | 636 }; |
| 638 }); | 637 }); |
| OLD | NEW |