Skip to content

Commit b628ebd

Browse files
authored
Merge pull request #351 from plotly/v0.9.2
Add strip tags to lib
2 parents fb14708 + 9bc2866 commit b628ebd

File tree

5 files changed

+258
-4
lines changed

5 files changed

+258
-4
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"react-dom": "^16.2.0",
2424
"react-select": "^1.0.0-rc.10",
2525
"react-tabs": "^2.2.1",
26-
"striptags": "^3.1.1",
2726
"tinycolor2": "^1.4.1"
2827
},
2928
"devDependencies": {

src/components/containers/Fold.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ import PropTypes from 'prop-types';
33
import React, {Component} from 'react';
44
import classnames from 'classnames';
55
import {CloseIcon, AngleDownIcon} from 'plotly-icons';
6-
import {unpackPlotProps, localize, containerConnectedContextTypes} from 'lib';
7-
import striptags from 'striptags';
6+
import {
7+
unpackPlotProps,
8+
localize,
9+
containerConnectedContextTypes,
10+
striptags,
11+
} from 'lib';
812

913
class Fold extends Component {
1014
constructor(props, context) {

src/components/fields/derived.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
connectLayoutToPlot,
88
connectToContainer,
99
supplyLayoutPlotProps,
10+
striptags,
1011
} from 'lib';
11-
import striptags from 'striptags';
1212

1313
export const CanvasSize = connectToContainer(UnconnectedNumeric, {
1414
modifyPlotProps: (props, context, plotProps) => {

src/lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from './customTraceType';
2121
import * as PlotlyIcons from 'plotly-icons';
2222
import supplyLayoutPlotProps from './supplyLayoutPlotProps';
23+
import striptags from './striptags';
2324

2425
function clamp(value, min, max) {
2526
return Math.max(min, Math.min(max, value));
@@ -71,4 +72,5 @@ export {
7172
unpackPlotProps,
7273
walkObject,
7374
supplyLayoutPlotProps,
75+
striptags,
7476
};

src/lib/striptags.js

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
/* eslint-disable */
2+
3+
// The MIT License (MIT)
4+
//
5+
// Copyright (c) [2017] [Eric Norris]
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to deal
9+
// in the Software without restriction, including without limitation the rights
10+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
// copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in all
15+
// copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
// SOFTWARE.
24+
25+
'use strict';
26+
27+
(function(global) {
28+
// minimal symbol polyfill for IE11 and others
29+
if (typeof Symbol !== 'function') {
30+
var Symbol = function(name) {
31+
return name;
32+
};
33+
34+
Symbol.nonNative = true;
35+
}
36+
37+
const STATE_PLAINTEXT = Symbol('plaintext');
38+
const STATE_HTML = Symbol('html');
39+
const STATE_COMMENT = Symbol('comment');
40+
41+
const ALLOWED_TAGS_REGEX = /<(\w*)>/g;
42+
const NORMALIZE_TAG_REGEX = /<\/?([^\s\/>]+)/;
43+
44+
function striptags(html, allowable_tags, tag_replacement) {
45+
html = html || '';
46+
allowable_tags = allowable_tags || [];
47+
tag_replacement = tag_replacement || '';
48+
49+
const context = init_context(allowable_tags, tag_replacement);
50+
51+
return striptags_internal(html, context);
52+
}
53+
54+
function init_striptags_stream(allowable_tags, tag_replacement) {
55+
allowable_tags = allowable_tags || [];
56+
tag_replacement = tag_replacement || '';
57+
58+
const context = init_context(allowable_tags, tag_replacement);
59+
60+
return function striptags_stream(html) {
61+
return striptags_internal(html || '', context);
62+
};
63+
}
64+
65+
striptags.init_streaming_mode = init_striptags_stream;
66+
67+
function init_context(allowable_tags, tag_replacement) {
68+
allowable_tags = parse_allowable_tags(allowable_tags);
69+
70+
return {
71+
allowable_tags: allowable_tags,
72+
tag_replacement: tag_replacement,
73+
74+
state: STATE_PLAINTEXT,
75+
tag_buffer: '',
76+
depth: 0,
77+
in_quote_char: '',
78+
};
79+
}
80+
81+
function striptags_internal(html, context) {
82+
const allowable_tags = context.allowable_tags;
83+
const tag_replacement = context.tag_replacement;
84+
85+
let state = context.state;
86+
let tag_buffer = context.tag_buffer;
87+
let depth = context.depth;
88+
let in_quote_char = context.in_quote_char;
89+
let output = '';
90+
91+
for (let idx = 0, length = html.length; idx < length; idx++) {
92+
const char = html[idx];
93+
94+
if (state === STATE_PLAINTEXT) {
95+
switch (char) {
96+
case '<':
97+
state = STATE_HTML;
98+
tag_buffer += char;
99+
break;
100+
101+
default:
102+
output += char;
103+
break;
104+
}
105+
} else if (state === STATE_HTML) {
106+
switch (char) {
107+
case '<':
108+
// ignore '<' if inside a quote
109+
if (in_quote_char) {
110+
break;
111+
}
112+
113+
// we're seeing a nested '<'
114+
depth++;
115+
break;
116+
117+
case '>':
118+
// ignore '>' if inside a quote
119+
if (in_quote_char) {
120+
break;
121+
}
122+
123+
// something like this is happening: '<<>>'
124+
if (depth) {
125+
depth--;
126+
127+
break;
128+
}
129+
130+
// this is closing the tag in tag_buffer
131+
in_quote_char = '';
132+
state = STATE_PLAINTEXT;
133+
tag_buffer += '>';
134+
135+
if (allowable_tags.has(normalize_tag(tag_buffer))) {
136+
output += tag_buffer;
137+
} else {
138+
output += tag_replacement;
139+
}
140+
141+
tag_buffer = '';
142+
break;
143+
144+
case '"':
145+
case "'":
146+
// catch both single and double quotes
147+
148+
if (char === in_quote_char) {
149+
in_quote_char = '';
150+
} else {
151+
in_quote_char = in_quote_char || char;
152+
}
153+
154+
tag_buffer += char;
155+
break;
156+
157+
case '-':
158+
if (tag_buffer === '<!-') {
159+
state = STATE_COMMENT;
160+
}
161+
162+
tag_buffer += char;
163+
break;
164+
165+
case ' ':
166+
case '\n':
167+
if (tag_buffer === '<') {
168+
state = STATE_PLAINTEXT;
169+
output += '< ';
170+
tag_buffer = '';
171+
172+
break;
173+
}
174+
175+
tag_buffer += char;
176+
break;
177+
178+
default:
179+
tag_buffer += char;
180+
break;
181+
}
182+
} else if (state === STATE_COMMENT) {
183+
switch (char) {
184+
case '>':
185+
if (tag_buffer.slice(-2) == '--') {
186+
// close the comment
187+
state = STATE_PLAINTEXT;
188+
}
189+
190+
tag_buffer = '';
191+
break;
192+
193+
default:
194+
tag_buffer += char;
195+
break;
196+
}
197+
}
198+
}
199+
200+
// save the context for future iterations
201+
context.state = state;
202+
context.tag_buffer = tag_buffer;
203+
context.depth = depth;
204+
context.in_quote_char = in_quote_char;
205+
206+
return output;
207+
}
208+
209+
function parse_allowable_tags(allowable_tags) {
210+
let tag_set = new Set();
211+
212+
if (typeof allowable_tags === 'string') {
213+
let match;
214+
215+
while ((match = ALLOWED_TAGS_REGEX.exec(allowable_tags))) {
216+
tag_set.add(match[1]);
217+
}
218+
} else if (
219+
!Symbol.nonNative &&
220+
typeof allowable_tags[Symbol.iterator] === 'function'
221+
) {
222+
tag_set = new Set(allowable_tags);
223+
} else if (typeof allowable_tags.forEach === 'function') {
224+
// IE11 compatible
225+
allowable_tags.forEach(tag_set.add, tag_set);
226+
}
227+
228+
return tag_set;
229+
}
230+
231+
function normalize_tag(tag_buffer) {
232+
const match = NORMALIZE_TAG_REGEX.exec(tag_buffer);
233+
234+
return match ? match[1].toLowerCase() : null;
235+
}
236+
237+
if (typeof define === 'function' && define.amd) {
238+
// AMD
239+
define(function module_factory() {
240+
return striptags;
241+
});
242+
} else if (typeof module === 'object' && module.exports) {
243+
// Node
244+
module.exports = striptags;
245+
} else {
246+
// Browser
247+
global.striptags = striptags;
248+
}
249+
})(this);

0 commit comments

Comments
 (0)