Commit 44ce9951 authored by estade@chromium.org's avatar estade@chromium.org

[settings] Don't inject user-provided text into document as html.

the culprit is innerHtml assignment. Instead, treat the text as text and create spans with createElement.

BUG=142964

Review URL: https://chromiumcodereview.appspot.com/10837295

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152206 0039d316-1c4b-4281-b951-d872f2087c98
parent 37d63d1f
...@@ -295,20 +295,9 @@ cr.define('options', function() { ...@@ -295,20 +295,9 @@ cr.define('options', function() {
this.unhighlightMatches_(); this.unhighlightMatches_();
this.removeSearchBubbles_(); this.removeSearchBubbles_();
// 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 replace string for hilighting
// search terms.
var regEx = new RegExp('(' + searchText + ')', 'ig');
var replaceString = '<span class="search-highlighted">$1</span>';
var page, length;
var pagesToSearch = this.getSearchablePages_(); var pagesToSearch = this.getSearchablePages_();
for (var key in pagesToSearch) { for (var key in pagesToSearch) {
page = pagesToSearch[key]; var page = pagesToSearch[key];
var elements = page.pageDiv.querySelectorAll('section'); var elements = page.pageDiv.querySelectorAll('section');
for (var i = 0, node; node = elements[i]; i++) { for (var i = 0, node; node = elements[i]; i++) {
node.classList.add('search-hidden'); node.classList.add('search-hidden');
...@@ -317,14 +306,21 @@ cr.define('options', function() { ...@@ -317,14 +306,21 @@ cr.define('options', function() {
var bubbleControls = []; var bubbleControls = [];
// 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 for hilighting search terms.
var regExp = new RegExp('(' + searchText + ')', 'ig');
if (searchText.length) { if (searchText.length) {
// Search all top-level sections for anchored string matches. // Search all top-level sections for anchored string matches.
for (var key in pagesToSearch) { for (var key in pagesToSearch) {
page = pagesToSearch[key]; var page = pagesToSearch[key];
var elements = var elements =
page.pageDiv.querySelectorAll('section'); page.pageDiv.querySelectorAll('section');
for (var i = 0, node; node = elements[i]; i++) { for (var i = 0, node; node = elements[i]; i++) {
if (this.performReplace_(regEx, replaceString, node)) { if (this.highlightMatches_(regExp, node)) {
node.classList.remove('search-hidden'); node.classList.remove('search-hidden');
if (!node.hidden) if (!node.hidden)
foundMatches = true; foundMatches = true;
...@@ -337,8 +333,8 @@ cr.define('options', function() { ...@@ -337,8 +333,8 @@ cr.define('options', function() {
var subPagesToSearch = this.getSearchableSubPages_(); var subPagesToSearch = this.getSearchableSubPages_();
var control, node; var control, node;
for (var key in subPagesToSearch) { for (var key in subPagesToSearch) {
page = subPagesToSearch[key]; var page = subPagesToSearch[key];
if (this.performReplace_(regEx, replaceString, page.pageDiv)) { if (this.highlightMatches_(regExp, page.pageDiv)) {
this.revealAssociatedSections_(page); this.revealAssociatedSections_(page);
bubbleControls = bubbleControls =
...@@ -390,14 +386,14 @@ cr.define('options', function() { ...@@ -390,14 +386,14 @@ cr.define('options', function() {
}, },
/** /**
* Performs a string replacement based on a regex and replace string. * Wraps matches in spans.
* @param {RegEx} regex A regular expression for finding search matches. * @param {RegExp} regExp The search query (in regexp form).
* @param {String} replace A string to apply the replace operation. * @param {Element} element An HTML container element to recursively search
* @param {Element} element An HTML container element. * within.
* @return {boolean} true if the element was changed. * @return {boolean} true if the element was changed.
* @private * @private
*/ */
performReplace_: function(regex, replace, element) { highlightMatches_: function(regExp, element) {
var found = false; var found = false;
var div, child, tmp; var div, child, tmp;
...@@ -408,30 +404,26 @@ cr.define('options', function() { ...@@ -408,30 +404,26 @@ cr.define('options', function() {
false); false);
var node = walker.nextNode(); var node = walker.nextNode();
while (node) { while (node) {
var textContent = node.nodeValue;
// Perform a search and replace on the text node value. // Perform a search and replace on the text node value.
var newValue = node.nodeValue.replace(regex, replace); var split = textContent.split(regExp);
if (newValue != node.nodeValue) { if (split.length > 1) {
// The text node has changed so that means we found at least one
// match.
found = true; found = true;
var nextNode = walker.nextNode();
// Create a temporary div element and set the innerHTML to the new var parentNode = node.parentNode;
// value. parentNode.removeChild(node);
div = document.createElement('div'); node = nextNode;
div.innerHTML = newValue;
for (var i = 0; i < split.length; ++i) {
// Insert all the child nodes of the temporary div element into the if (i % 2 == 0) {
// document, before the original node. parentNode.appendChild(document.createTextNode(split[i]));
child = div.firstChild; } else {
while (child = div.firstChild) { var span = document.createElement('span');
node.parentNode.insertBefore(child, node); span.className = 'search-highlighted';
span.textContent = split[i];
parentNode.appendChild(span);
}
} }
// Delete the old text node and advance the walker to the next
// node.
tmp = node;
node = walker.nextNode();
tmp.parentNode.removeChild(tmp);
} else { } else {
node = walker.nextNode(); node = walker.nextNode();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment