Replace the implementation of escapeTextContentForBrowser with escape-html (#6862)
* Replacing the implementation of escapeTextContentForBrowser with escape-html for performance * Addressing @spicyj's code review comment here: https://github.com/facebook/react/pull/6862#issuecomment-223102868 . Pulled the code of escape-html in to react and changed the encoding of single quote to '. * Addressing code review comment https://github.com/facebook/react/pull/6862#discussion_r65462074 to make code more inlinable for v8. Thanks, @spicyj.
Sasha Aickin committed
Jun 1, 2016 at 17:14 UTC
d6e70586b77d4d52c4046b007b8a619e4463058c
1 file changed
+94
-12
src/renderers/dom/shared/escapeTextContentForBrowser.js
+94
-12
@@ -1,29 +1,105 @@
1
/**
2
- * Copyright 2013-present, Facebook, Inc.
2
+ * Copyright 2016-present, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
+ * Based on the escape-html library, which is used under the MIT License below:
10
+ *
11
+ * Copyright (c) 2012-2013 TJ Holowaychuk
12
+ * Copyright (c) 2015 Andreas Lubbe
13
+ * Copyright (c) 2015 Tiancheng "Timothy" Gu
14
+ *
15
+ * Permission is hereby granted, free of charge, to any person obtaining
16
+ * a copy of this software and associated documentation files (the
17
+ * 'Software'), to deal in the Software without restriction, including
18
+ * without limitation the rights to use, copy, modify, merge, publish,
19
+ * distribute, sublicense, and/or sell copies of the Software, and to
20
+ * permit persons to whom the Software is furnished to do so, subject to
21
+ * the following conditions:
22
+ *
23
+ * The above copyright notice and this permission notice shall be
24
+ * included in all copies or substantial portions of the Software.
25
+ *
26
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
27
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
30
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
+ *
34
* @providesModule escapeTextContentForBrowser
35
*/
36
37
'use strict';
38
14
-var ESCAPE_LOOKUP = {
15
- '&': '&',
16
- '>': '>',
17
- '<': '<',
18
- '"': '"',
19
- '\'': ''',
20
-};
39
+// code copied and modified from escape-html
40
+/**
41
+ * Module variables.
42
+ * @private
43
+ */
44
+
45
+var matchHtmlRegExp = /["'&<>]/;
46
+
47
+/**
48
+ * Escape special characters in the given string of html.
49
+ *
50
+ * @param {string} string The string to escape for inserting into HTML
51
+ * @return {string}
52
+ * @public
53
+ */
54
+
55
+function escapeHtml(string) {
56
+ var str = '' + string;
57
+ var match = matchHtmlRegExp.exec(str);
58
+
59
+ if (!match) {
60
+ return str;
61
+ }
62
22
-var ESCAPE_REGEX = /[&><"']/g;
63
+ var escape;
64
+ var html = '';
65
+ var index = 0;
66
+ var lastIndex = 0;
67
24
-function escaper(match) {
25
- return ESCAPE_LOOKUP[match];
68
+ for (index = match.index; index < str.length; index++) {
69
+ switch (str.charCodeAt(index)) {
70
+ case 34: // "
71
+ escape = '"';
72
+ break;
73
+ case 38: // &
74
+ escape = '&';
75
+ break;
76
+ case 39: // '
77
+ escape = '''; // modified from escape-html; used to be '''
78
+ break;
79
+ case 60: // <
80
+ escape = '<';
81
+ break;
82
+ case 62: // >
83
+ escape = '>';
84
+ break;
85
+ default:
86
+ continue;
87
+ }
88
+
89
+ if (lastIndex !== index) {
90
+ html += str.substring(lastIndex, index);
91
+ }
92
+
93
+ lastIndex = index + 1;
94
+ html += escape;
95
+ }
96
+
97
+ return lastIndex !== index
98
+ ? html + str.substring(lastIndex, index)
99
+ : html;
100
}
101
+// end code copied and modified from escape-html
102
+
103
104
/**
105
* Escapes text to prevent scripting attacks.
@@ -32,7 +108,13 @@ function escaper(match) {
108
* @return {string} An escaped string.
109
*/
110
function escapeTextContentForBrowser(text) {
35
- return ('' + text).replace(ESCAPE_REGEX, escaper);
111
+ if (typeof text === 'boolean' || typeof text === 'number') {
112
+ // this shortcircuit helps perf for types that we know will never have
113
+ // special characters, especially given that this function is used often
114
+ // for numeric dom ids.
115
+ return '' + text;
116
+ }
117
+ return escapeHtml(text);
118
}
119
120
module.exports = escapeTextContentForBrowser;