preact-render-to-string 5.1.7 → 5.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.js CHANGED
@@ -1,4 +1,11 @@
1
- import { encodeEntities, indent, isLargeString, styleObjToCss, assign, getChildren } from './util';
1
+ import {
2
+ encodeEntities,
3
+ indent,
4
+ isLargeString,
5
+ styleObjToCss,
6
+ assign,
7
+ getChildren
8
+ } from './util';
2
9
  import { options, Fragment, createElement } from 'preact';
3
10
 
4
11
  const SHALLOW = { shallow: true };
@@ -10,7 +17,6 @@ const VOID_ELEMENTS = /^(area|base|br|col|embed|hr|img|input|link|meta|param|sou
10
17
 
11
18
  const noop = () => {};
12
19
 
13
-
14
20
  /** Render Preact JSX + Components to an HTML string.
15
21
  * @name render
16
22
  * @function
@@ -20,10 +26,10 @@ const noop = () => {};
20
26
  * @param {Boolean} [options.shallow=false] If `true`, renders nested Components as HTML elements (`<Foo a="b" />`).
21
27
  * @param {Boolean} [options.xml=false] If `true`, uses self-closing tags for elements without children.
22
28
  * @param {Boolean} [options.pretty=false] If `true`, adds whitespace for readability
29
+ * @param {RegEx|undefined} [options.voidElements] RegeEx that matches elements that are considered void (self-closing)
23
30
  */
24
31
  renderToString.render = renderToString;
25
32
 
26
-
27
33
  /** Only render elements, leaving Components inline as `<ComponentName ... />`.
28
34
  * This method is just a convenience alias for `render(vnode, context, { shallow:true })`
29
35
  * @name shallow
@@ -33,10 +39,9 @@ renderToString.render = renderToString;
33
39
  */
34
40
  let shallowRender = (vnode, context) => renderToString(vnode, context, SHALLOW);
35
41
 
36
-
37
42
  /** The default export is an alias of `render()`. */
38
43
  function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
39
- if (vnode==null || typeof vnode==='boolean') {
44
+ if (vnode == null || typeof vnode === 'boolean') {
40
45
  return '';
41
46
  }
42
47
 
@@ -52,33 +57,40 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
52
57
  opts = opts || {};
53
58
 
54
59
  let pretty = opts.pretty,
55
- indentChar = pretty && typeof pretty==='string' ? pretty : '\t';
60
+ indentChar = pretty && typeof pretty === 'string' ? pretty : '\t';
56
61
 
57
62
  // #text nodes
58
- if (typeof vnode!=='object' && !nodeName) {
63
+ if (typeof vnode !== 'object' && !nodeName) {
59
64
  return encodeEntities(vnode);
60
65
  }
61
66
 
62
67
  // components
63
- if (typeof nodeName==='function') {
68
+ if (typeof nodeName === 'function') {
64
69
  isComponent = true;
65
- if (opts.shallow && (inner || opts.renderRootComponent===false)) {
70
+ if (opts.shallow && (inner || opts.renderRootComponent === false)) {
66
71
  nodeName = getComponentName(nodeName);
67
- }
68
- else if (nodeName===Fragment) {
72
+ } else if (nodeName === Fragment) {
69
73
  let rendered = '';
70
74
  let children = [];
71
75
  getChildren(children, vnode.props.children);
72
76
 
73
77
  for (let i = 0; i < children.length; i++) {
74
- rendered += (i > 0 && pretty ? '\n' : '') + renderToString(children[i], context, opts, opts.shallowHighOrder!==false, isSvgMode, selectValue);
78
+ rendered +=
79
+ (i > 0 && pretty ? '\n' : '') +
80
+ renderToString(
81
+ children[i],
82
+ context,
83
+ opts,
84
+ opts.shallowHighOrder !== false,
85
+ isSvgMode,
86
+ selectValue
87
+ );
75
88
  }
76
89
  return rendered;
77
- }
78
- else {
90
+ } else {
79
91
  let rendered;
80
92
 
81
- let c = vnode.__c = {
93
+ let c = (vnode.__c = {
82
94
  __v: vnode,
83
95
  context,
84
96
  props: vnode.props,
@@ -87,26 +99,41 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
87
99
  forceUpdate: noop,
88
100
  // hooks
89
101
  __h: []
90
- };
102
+ });
103
+
104
+ // options._diff
105
+ if (options.__b) options.__b(vnode);
91
106
 
92
- // options.render
107
+ // options._render
93
108
  if (options.__r) options.__r(vnode);
94
109
 
95
- if (!nodeName.prototype || typeof nodeName.prototype.render!=='function') {
110
+ if (
111
+ !nodeName.prototype ||
112
+ typeof nodeName.prototype.render !== 'function'
113
+ ) {
96
114
  // Necessary for createContext api. Setting this property will pass
97
115
  // the context value as `this.context` just for this component.
98
116
  let cxType = nodeName.contextType;
99
117
  let provider = cxType && context[cxType.__c];
100
- let cctx = cxType != null ? (provider ? provider.props.value : cxType.__) : context;
118
+ let cctx =
119
+ cxType != null
120
+ ? provider
121
+ ? provider.props.value
122
+ : cxType.__
123
+ : context;
101
124
 
102
125
  // stateless functional components
103
126
  rendered = nodeName.call(vnode.__c, props, cctx);
104
- }
105
- else {
127
+ } else {
106
128
  // class-based components
107
129
  let cxType = nodeName.contextType;
108
130
  let provider = cxType && context[cxType.__c];
109
- let cctx = cxType != null ? (provider ? provider.props.value : cxType.__) : context;
131
+ let cctx =
132
+ cxType != null
133
+ ? provider
134
+ ? provider.props.value
135
+ : cxType.__
136
+ : context;
110
137
 
111
138
  // c = new nodeName(props, context);
112
139
  c = vnode.__c = new nodeName(props, cctx);
@@ -114,21 +141,30 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
114
141
  // turn off stateful re-rendering:
115
142
  c._dirty = c.__d = true;
116
143
  c.props = props;
117
- if (c.state==null) c.state = {};
144
+ if (c.state == null) c.state = {};
118
145
 
119
- if (c._nextState==null && c.__s==null) {
146
+ if (c._nextState == null && c.__s == null) {
120
147
  c._nextState = c.__s = c.state;
121
148
  }
122
149
 
123
150
  c.context = cctx;
124
- if (nodeName.getDerivedStateFromProps) c.state = assign(assign({}, c.state), nodeName.getDerivedStateFromProps(c.props, c.state));
125
- else if (c.componentWillMount) c.componentWillMount();
126
-
127
- // If the user called setState in cWM we need to flush pending,
128
- // state updates. This is the same behaviour in React.
129
- c.state = c._nextState !== c.state
130
- ? c._nextState : c.__s!==c.state
131
- ? c.__s : c.state;
151
+ if (nodeName.getDerivedStateFromProps)
152
+ c.state = assign(
153
+ assign({}, c.state),
154
+ nodeName.getDerivedStateFromProps(c.props, c.state)
155
+ );
156
+ else if (c.componentWillMount) {
157
+ c.componentWillMount();
158
+
159
+ // If the user called setState in cWM we need to flush pending,
160
+ // state updates. This is the same behaviour in React.
161
+ c.state =
162
+ c._nextState !== c.state
163
+ ? c._nextState
164
+ : c.__s !== c.state
165
+ ? c.__s
166
+ : c.state;
167
+ }
132
168
 
133
169
  rendered = c.render(c.props, c.state, c.context);
134
170
  }
@@ -137,51 +173,85 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
137
173
  context = assign(assign({}, context), c.getChildContext());
138
174
  }
139
175
 
140
- return renderToString(rendered, context, opts, opts.shallowHighOrder!==false, isSvgMode, selectValue);
176
+ return renderToString(
177
+ rendered,
178
+ context,
179
+ opts,
180
+ opts.shallowHighOrder !== false,
181
+ isSvgMode,
182
+ selectValue
183
+ );
141
184
  }
142
185
  }
143
186
 
144
187
  // render JSX to HTML
145
- let s = '', html;
188
+ let s = '',
189
+ propChildren,
190
+ html;
146
191
 
147
192
  if (props) {
148
193
  let attrs = Object.keys(props);
149
194
 
150
195
  // allow sorting lexicographically for more determinism (useful for tests, such as via preact-jsx-chai)
151
- if (opts && opts.sortAttributes===true) attrs.sort();
196
+ if (opts && opts.sortAttributes === true) attrs.sort();
152
197
 
153
- for (let i=0; i<attrs.length; i++) {
198
+ for (let i = 0; i < attrs.length; i++) {
154
199
  let name = attrs[i],
155
200
  v = props[name];
156
- if (name==='children') continue;
201
+ if (name === 'children') {
202
+ propChildren = v;
203
+ continue;
204
+ }
157
205
 
158
206
  if (name.match(/[\s\n\\/='"\0<>]/)) continue;
159
207
 
160
- if (!(opts && opts.allAttributes) && (name==='key' || name==='ref')) continue;
208
+ if (
209
+ !(opts && opts.allAttributes) &&
210
+ (name === 'key' ||
211
+ name === 'ref' ||
212
+ name === '__self' ||
213
+ name === '__source' ||
214
+ name === 'defaultValue')
215
+ )
216
+ continue;
161
217
 
162
- if (name==='className') {
218
+ if (name === 'className') {
163
219
  if (props.class) continue;
164
220
  name = 'class';
165
- }
166
- else if (isSvgMode && name.match(/^xlink:?./)) {
221
+ } else if (isSvgMode && name.match(/^xlink:?./)) {
167
222
  name = name.toLowerCase().replace(/^xlink:?/, 'xlink:');
168
223
  }
169
224
 
170
- if (name==='style' && v && typeof v==='object') {
225
+ if (name === 'htmlFor') {
226
+ if (props.for) continue;
227
+ name = 'for';
228
+ }
229
+
230
+ if (name === 'style' && v && typeof v === 'object') {
171
231
  v = styleObjToCss(v);
172
232
  }
173
233
 
174
- let hooked = opts.attributeHook && opts.attributeHook(name, v, context, opts, isComponent);
175
- if (hooked || hooked==='') {
234
+ // always use string values instead of booleans for aria attributes
235
+ // also see https://github.com/preactjs/preact/pull/2347/files
236
+ if (name[0] === 'a' && name['1'] === 'r' && typeof v === 'boolean') {
237
+ v = String(v);
238
+ }
239
+
240
+ let hooked =
241
+ opts.attributeHook &&
242
+ opts.attributeHook(name, v, context, opts, isComponent);
243
+ if (hooked || hooked === '') {
176
244
  s += hooked;
177
245
  continue;
178
246
  }
179
247
 
180
- if (name==='dangerouslySetInnerHTML') {
248
+ if (name === 'dangerouslySetInnerHTML') {
181
249
  html = v && v.__html;
182
- }
183
- else if ((v || v===0 || v==='') && typeof v!=='function') {
184
- if (v===true || v==='') {
250
+ } else if (nodeName === 'textarea' && name === 'value') {
251
+ // <textarea value="a&b"> --> <textarea>a&amp;b</textarea>
252
+ propChildren = v;
253
+ } else if ((v || v === 0 || v === '') && typeof v !== 'function') {
254
+ if (v === true || v === '') {
185
255
  v = name;
186
256
  // in non-xml mode, allow boolean attributes
187
257
  if (!opts || !opts.xml) {
@@ -190,12 +260,11 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
190
260
  }
191
261
  }
192
262
 
193
- if (name==='value') {
194
- if (nodeName==='select') {
263
+ if (name === 'value') {
264
+ if (nodeName === 'select') {
195
265
  selectValue = v;
196
266
  continue;
197
- }
198
- else if (nodeName==='option' && selectValue==v) {
267
+ } else if (nodeName === 'option' && selectValue == v) {
199
268
  s += ` selected`;
200
269
  }
201
270
  }
@@ -207,16 +276,17 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
207
276
  // account for >1 multiline attribute
208
277
  if (pretty) {
209
278
  let sub = s.replace(/^\n\s*/, ' ');
210
- if (sub!==s && !~sub.indexOf('\n')) s = sub;
279
+ if (sub !== s && !~sub.indexOf('\n')) s = sub;
211
280
  else if (pretty && ~s.indexOf('\n')) s += '\n';
212
281
  }
213
282
 
214
283
  s = `<${nodeName}${s}>`;
215
- if (String(nodeName).match(/[\s\n\\/='"\0<>]/)) throw new Error(`${nodeName} is not a valid HTML tag name in ${s}`);
216
-
217
- let isVoid = String(nodeName).match(VOID_ELEMENTS);
218
- if (isVoid) s = s.replace(/>$/, ' />');
284
+ if (String(nodeName).match(/[\s\n\\/='"\0<>]/))
285
+ throw new Error(`${nodeName} is not a valid HTML tag name in ${s}`);
219
286
 
287
+ let isVoid =
288
+ String(nodeName).match(VOID_ELEMENTS) ||
289
+ (opts.voidElements && String(nodeName).match(opts.voidElements));
220
290
  let pieces = [];
221
291
 
222
292
  let children;
@@ -226,44 +296,56 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
226
296
  html = '\n' + indentChar + indent(html, indentChar);
227
297
  }
228
298
  s += html;
229
- }
230
- else if (props && getChildren(children = [], props.children).length) {
299
+ } else if (
300
+ propChildren != null &&
301
+ getChildren((children = []), propChildren).length
302
+ ) {
231
303
  let hasLarge = pretty && ~s.indexOf('\n');
232
304
  let lastWasText = false;
233
305
 
234
- for (let i=0; i<children.length; i++) {
306
+ for (let i = 0; i < children.length; i++) {
235
307
  let child = children[i];
236
308
 
237
- if (child!=null && child!==false) {
238
- let childSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode,
239
- ret = renderToString(child, context, opts, true, childSvgMode, selectValue);
309
+ if (child != null && child !== false) {
310
+ let childSvgMode =
311
+ nodeName === 'svg'
312
+ ? true
313
+ : nodeName === 'foreignObject'
314
+ ? false
315
+ : isSvgMode,
316
+ ret = renderToString(
317
+ child,
318
+ context,
319
+ opts,
320
+ true,
321
+ childSvgMode,
322
+ selectValue
323
+ );
240
324
 
241
325
  if (pretty && !hasLarge && isLargeString(ret)) hasLarge = true;
242
326
 
243
327
  // Skip if we received an empty string
244
328
  if (ret) {
245
329
  if (pretty) {
246
- let isText = ret.length > 0 && ret[0]!='<';
247
-
330
+ let isText = ret.length > 0 && ret[0] != '<';
331
+
248
332
  // We merge adjacent text nodes, otherwise each piece would be printed
249
333
  // on a new line.
250
334
  if (lastWasText && isText) {
251
- pieces[pieces.length -1] += ret;
252
- }
253
- else {
335
+ pieces[pieces.length - 1] += ret;
336
+ } else {
254
337
  pieces.push(ret);
255
338
  }
256
339
 
257
340
  lastWasText = isText;
258
- }
259
- else {
341
+ } else {
260
342
  pieces.push(ret);
261
343
  }
262
344
  }
263
345
  }
264
346
  }
265
347
  if (pretty && hasLarge) {
266
- for (let i=pieces.length; i--; ) {
348
+ for (let i = pieces.length; i--; ) {
267
349
  pieces[i] = '\n' + indentChar + indent(pieces[i], indentChar);
268
350
  }
269
351
  }
@@ -271,12 +353,13 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
271
353
 
272
354
  if (pieces.length) {
273
355
  s += pieces.join('');
274
- }
275
- else if (opts && opts.xml) {
276
- return s.substring(0, s.length-1) + ' />';
356
+ } else if (opts && opts.xml) {
357
+ return s.substring(0, s.length - 1) + ' />';
277
358
  }
278
359
 
279
- if (!isVoid) {
360
+ if (isVoid && !children) {
361
+ s = s.replace(/>$/, ' />');
362
+ } else {
280
363
  if (pretty && ~s.indexOf('\n')) s += '\n';
281
364
  s += `</${nodeName}>`;
282
365
  }
@@ -285,7 +368,11 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
285
368
  }
286
369
 
287
370
  function getComponentName(component) {
288
- return component.displayName || component!==Function && component.name || getFallbackComponentName(component);
371
+ return (
372
+ component.displayName ||
373
+ (component !== Function && component.name) ||
374
+ getFallbackComponentName(component)
375
+ );
289
376
  }
290
377
 
291
378
  function getFallbackComponentName(component) {
@@ -294,14 +381,14 @@ function getFallbackComponentName(component) {
294
381
  if (!name) {
295
382
  // search for an existing indexed name for the given component:
296
383
  let index = -1;
297
- for (let i=UNNAMED.length; i--; ) {
298
- if (UNNAMED[i]===component) {
384
+ for (let i = UNNAMED.length; i--; ) {
385
+ if (UNNAMED[i] === component) {
299
386
  index = i;
300
387
  break;
301
388
  }
302
389
  }
303
390
  // not found, create a new indexed name:
304
- if (index<0) {
391
+ if (index < 0) {
305
392
  index = UNNAMED.push(component) - 1;
306
393
  }
307
394
  name = `UnnamedComponent${index}`;
@@ -314,6 +401,7 @@ export default renderToString;
314
401
 
315
402
  export {
316
403
  renderToString as render,
404
+ renderToString as renderToStaticMarkup,
317
405
  renderToString,
318
406
  shallowRender
319
407
  };
package/src/jsx.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import { VNode } from 'preact';
2
2
 
3
3
  interface Options {
4
- jsx?: boolean;
5
- xml?: boolean;
6
- functions?: boolean
7
- functionNames?: boolean,
8
- skipFalseAttributes?: boolean
9
- pretty?: boolean | string;
4
+ jsx?: boolean;
5
+ xml?: boolean;
6
+ functions?: boolean;
7
+ functionNames?: boolean;
8
+ skipFalseAttributes?: boolean;
9
+ pretty?: boolean | string;
10
10
  }
11
11
 
12
- export function render(vnode: VNode, context?: any, options?: Options):string;
12
+ export function render(vnode: VNode, context?: any, options?: Options): string;
13
13
  export default render;
package/src/jsx.js CHANGED
@@ -3,45 +3,53 @@ import renderToString from './index';
3
3
  import { indent, encodeEntities, assign } from './util';
4
4
  import prettyFormat from 'pretty-format';
5
5
 
6
-
7
6
  // we have to patch in Array support, Possible issue in npm.im/pretty-format
8
7
  let preactPlugin = {
9
8
  test(object) {
10
- return object && typeof object==='object' && 'type' in object && 'props' in object && 'key' in object;
9
+ return (
10
+ object &&
11
+ typeof object === 'object' &&
12
+ 'type' in object &&
13
+ 'props' in object &&
14
+ 'key' in object
15
+ );
11
16
  },
12
17
  print(val, print, indent) {
13
18
  return renderToString(val, preactPlugin.context, preactPlugin.opts, true);
14
19
  }
15
20
  };
16
21
 
17
-
18
22
  let prettyFormatOpts = {
19
23
  plugins: [preactPlugin]
20
24
  };
21
25
 
22
-
23
26
  function attributeHook(name, value, context, opts, isComponent) {
24
27
  let type = typeof value;
25
-
28
+
26
29
  // Use render-to-string's built-in handling for these properties
27
- if (name==='dangerouslySetInnerHTML') return false;
30
+ if (name === 'dangerouslySetInnerHTML') return false;
28
31
 
29
32
  // always skip null & undefined values, skip false DOM attributes, skip functions if told to
30
- if (value==null || (type==='function' && !opts.functions)) return '';
33
+ if (value == null || (type === 'function' && !opts.functions)) return '';
31
34
 
32
- if (opts.skipFalseAttributes && !isComponent && (value===false || ((name==='class' || name==='style') && value===''))) return '';
35
+ if (
36
+ opts.skipFalseAttributes &&
37
+ !isComponent &&
38
+ (value === false ||
39
+ ((name === 'class' || name === 'style') && value === ''))
40
+ )
41
+ return '';
33
42
 
34
- let indentChar = typeof opts.pretty==='string' ? opts.pretty : '\t';
35
- if (type!=='string') {
36
- if (type==='function' && !opts.functionNames) {
43
+ let indentChar = typeof opts.pretty === 'string' ? opts.pretty : '\t';
44
+ if (type !== 'string') {
45
+ if (type === 'function' && !opts.functionNames) {
37
46
  value = 'Function';
38
- }
39
- else {
47
+ } else {
40
48
  preactPlugin.context = context;
41
49
  preactPlugin.opts = opts;
42
50
  value = prettyFormat(value, prettyFormatOpts);
43
51
  if (~value.indexOf('\n')) {
44
- value = `${indent('\n'+value, indentChar)}\n`;
52
+ value = `${indent('\n' + value, indentChar)}\n`;
45
53
  }
46
54
  }
47
55
  return indent(`\n${name}={${value}}`, indentChar);
@@ -49,7 +57,6 @@ function attributeHook(name, value, context, opts, isComponent) {
49
57
  return `\n${indentChar}${name}="${encodeEntities(value)}"`;
50
58
  }
51
59
 
52
-
53
60
  let defaultOpts = {
54
61
  attributeHook,
55
62
  jsx: true,
@@ -60,7 +67,6 @@ let defaultOpts = {
60
67
  pretty: ' '
61
68
  };
62
69
 
63
-
64
70
  function renderToJsxString(vnode, context, opts, inner) {
65
71
  opts = assign(assign({}, defaultOpts), opts || {});
66
72
  return renderToString(vnode, context, opts, inner);
package/src/polyfills.js CHANGED
@@ -1,7 +1,8 @@
1
- if (typeof Symbol!=='function') {
1
+ if (typeof Symbol !== 'function') {
2
2
  let c = 0;
3
- Symbol = function(s) { // eslint-disable-line
3
+ // eslint-disable-next-line
4
+ Symbol = function (s) {
4
5
  return `@@${s}${++c}`;
5
6
  };
6
- Symbol.for = s => `@@${s}`;
7
+ Symbol.for = (s) => `@@${s}`;
7
8
  }
package/src/util.js CHANGED
@@ -1,15 +1,30 @@
1
1
  // DOM properties that should NOT have "px" added when numeric
2
2
  export const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i;
3
3
 
4
- export let encodeEntities = s => String(s)
5
- .replace(/&/g, '&amp;')
6
- .replace(/</g, '&lt;')
7
- .replace(/>/g, '&gt;')
8
- .replace(/"/g, '&quot;');
4
+ export function encodeEntities(s) {
5
+ if (typeof s !== 'string') s = String(s);
6
+ let out = '';
7
+ for (let i = 0; i < s.length; i++) {
8
+ let ch = s[i];
9
+ // prettier-ignore
10
+ switch (ch) {
11
+ case '<': out += '&lt;'; break;
12
+ case '>': out += '&gt;'; break;
13
+ case '"': out += '&quot;'; break;
14
+ case '&': out += '&amp;'; break;
15
+ default: out += ch;
16
+ }
17
+ }
18
+ return out;
19
+ }
9
20
 
10
- export let indent = (s, char) => String(s).replace(/(\n+)/g, '$1' + (char || '\t'));
21
+ export let indent = (s, char) =>
22
+ String(s).replace(/(\n+)/g, '$1' + (char || '\t'));
11
23
 
12
- export let isLargeString = (s, length, ignoreLines) => (String(s).length>(length || 40) || (!ignoreLines && String(s).indexOf('\n')!==-1) || String(s).indexOf('<')!==-1);
24
+ export let isLargeString = (s, length, ignoreLines) =>
25
+ String(s).length > (length || 40) ||
26
+ (!ignoreLines && String(s).indexOf('\n') !== -1) ||
27
+ String(s).indexOf('<') !== -1;
13
28
 
14
29
  const JS_TO_CSS = {};
15
30
 
@@ -18,13 +33,17 @@ export function styleObjToCss(s) {
18
33
  let str = '';
19
34
  for (let prop in s) {
20
35
  let val = s[prop];
21
- if (val!=null) {
36
+ if (val != null) {
22
37
  if (str) str += ' ';
23
38
  // str += jsToCss(prop);
24
- str += JS_TO_CSS[prop] || (JS_TO_CSS[prop] = prop.replace(/([A-Z])/g,'-$1').toLowerCase());
39
+ str +=
40
+ prop[0] == '-'
41
+ ? prop
42
+ : JS_TO_CSS[prop] ||
43
+ (JS_TO_CSS[prop] = prop.replace(/([A-Z])/g, '-$1').toLowerCase());
25
44
  str += ': ';
26
45
  str += val;
27
- if (typeof val==='number' && IS_NON_DIMENSIONAL.test(prop)===false) {
46
+ if (typeof val === 'number' && IS_NON_DIMENSIONAL.test(prop) === false) {
28
47
  str += 'px';
29
48
  }
30
49
  str += ';';
@@ -55,8 +74,7 @@ export function assign(obj, props) {
55
74
  export function getChildren(accumulator, children) {
56
75
  if (Array.isArray(children)) {
57
76
  children.reduce(getChildren, accumulator);
58
- }
59
- else if (children!=null && children!==false) {
77
+ } else if (children != null && children !== false) {
60
78
  accumulator.push(children);
61
79
  }
62
80
  return accumulator;