preact-render-to-string
Advanced tools
Comparing version 2.8.0 to 3.0.0
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.preactRenderToString = factory()); | ||
}(this, function () { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('pretty-format')) : | ||
typeof define === 'function' && define.amd ? define(['pretty-format'], factory) : | ||
(global.preactRenderToString = factory(global.prettyFormat)); | ||
}(this, function (prettyFormat) { | ||
prettyFormat = 'default' in prettyFormat ? prettyFormat['default'] : prettyFormat; | ||
var SHALLOW = { shallow: true }; | ||
@@ -58,4 +60,4 @@ | ||
var isLargeString = function (s) { | ||
return String(s).length > 40 || String(s).indexOf('\n') !== -1 || String(s).indexOf('<') !== -1; | ||
var isLargeString = function (s, length, ignoreLines) { | ||
return String(s).length > (length || 40) || !ignoreLines && String(s).indexOf('\n') !== -1 || String(s).indexOf('<') !== -1; | ||
}; | ||
@@ -99,2 +101,15 @@ | ||
var preactPlugin = { | ||
test: function (object) { | ||
return object && typeof object === 'object' && 'nodeName' in object && 'attributes' in object && 'children' in object && !('nodeType' in object); | ||
}, | ||
print: function (val, print, indent) { | ||
return renderToString(val, preactPlugin.context, preactPlugin.opts, true); | ||
} | ||
}; | ||
var prettyFormatOpts = { | ||
plugins: [preactPlugin] | ||
}; | ||
renderToString.render = renderToString; | ||
@@ -140,3 +155,3 @@ | ||
if (c.getChildContext) { | ||
context = c.getChildContext(); | ||
context = assign(assign({}, context), c.getChildContext()); | ||
} | ||
@@ -149,3 +164,3 @@ } | ||
var s = '<' + nodeName, | ||
var s = '', | ||
html = void 0; | ||
@@ -163,2 +178,18 @@ | ||
if (!(opts && opts.allAttributes) && (name === 'key' || name === 'ref')) continue; | ||
if (opts.jsx) { | ||
if (typeof v !== 'string') { | ||
preactPlugin.context = context; | ||
preactPlugin.opts = opts; | ||
v = prettyFormat(v, prettyFormatOpts); | ||
if (~v.indexOf('\n')) { | ||
v = indent('\n' + v, indentChar) + '\n'; | ||
} | ||
s += indent('\n' + name + '={' + v + '}', indentChar); | ||
} else { | ||
s += '\n' + indentChar + name + '="' + encodeEntities(v) + '"'; | ||
} | ||
continue; | ||
} | ||
if (name === 'className') { | ||
@@ -171,2 +202,3 @@ if (attributes['class']) continue; | ||
} | ||
if (name === 'dangerouslySetInnerHTML') { | ||
@@ -188,4 +220,7 @@ html = v && v.__html; | ||
s += '>'; | ||
var sub = s.replace(/^\n\s*/, ' '); | ||
if (sub !== s && !~sub.indexOf('\n')) s = sub;else if (~s.indexOf('\n')) s += '\n'; | ||
s = '<' + nodeName + s + '>'; | ||
if (html) { | ||
@@ -200,3 +235,3 @@ if (pretty && isLargeString(html)) { | ||
var pieces = [], | ||
hasLarge = false; | ||
hasLarge = ~s.indexOf('\n'); | ||
for (var _i = 0; _i < len; _i++) { | ||
@@ -203,0 +238,0 @@ var child = children[_i]; |
{ | ||
"name": "preact-render-to-string", | ||
"amdName": "preactRenderToString", | ||
"version": "2.8.0", | ||
"version": "3.0.0", | ||
"description": "Render JSX to an HTML string, with support for Preact components.", | ||
@@ -44,12 +44,15 @@ "main": "dist/index.js", | ||
"babel-register": "^6.9.0", | ||
"chai": "^3.3.0", | ||
"chai": "^3.5.0", | ||
"eslint": "^3.1.1", | ||
"mocha": "^2.3.3", | ||
"mocha": "^3.0.0", | ||
"preact": "^5.5.0", | ||
"rollup": "^0.34.1", | ||
"rollup": "^0.34.2", | ||
"rollup-plugin-babel": "^2.6.1", | ||
"rollup-plugin-memory": "^1.0.0", | ||
"sinon": "^1.17.1", | ||
"sinon": "^1.17.5", | ||
"sinon-chai": "^2.8.0" | ||
}, | ||
"dependencies": { | ||
"pretty-format": "^3.5.1" | ||
} | ||
} |
@@ -0,1 +1,2 @@ | ||
import prettyFormat from 'pretty-format'; | ||
@@ -56,3 +57,3 @@ const SHALLOW = { shallow: true }; | ||
let isLargeString = s => (String(s).length>40 || String(s).indexOf('\n')!==-1 || String(s).indexOf('<')!==-1); | ||
let isLargeString = (s, length, ignoreLines) => (String(s).length>(length || 40) || (!ignoreLines && String(s).indexOf('\n')!==-1) || String(s).indexOf('<')!==-1); | ||
@@ -93,2 +94,16 @@ function styleObjToCss(s) { | ||
// we have to patch in Array support, Possible issue in npm.im/pretty-format | ||
let preactPlugin = { | ||
test(object) { | ||
return object && typeof object==='object' && 'nodeName' in object && 'attributes' in object && 'children' in object && !('nodeType' in object); | ||
}, | ||
print(val, print, indent) { | ||
return renderToString(val, preactPlugin.context, preactPlugin.opts, true); | ||
} | ||
}; | ||
let prettyFormatOpts = { | ||
plugins: [preactPlugin] | ||
}; | ||
/** Render Preact JSX + Components to an HTML string. | ||
@@ -117,10 +132,2 @@ * @name render | ||
/** You can actually skip preact entirely and import this empty Component base class (or not use a base class at all). | ||
* preact-render-to-string doesn't use any of Preact's functionality to do its job. | ||
* @name Component | ||
* @class | ||
*/ | ||
// renderToString.Component = function Component(){}; | ||
/** The default export is an alias of `render()`. */ | ||
@@ -162,3 +169,3 @@ export default function renderToString(vnode, context, opts, inner) { | ||
if (c.getChildContext) { | ||
context = c.getChildContext(); | ||
context = assign(assign({}, context), c.getChildContext()); | ||
} | ||
@@ -172,4 +179,3 @@ } | ||
// render JSX to HTML | ||
let s = `<${nodeName}`, | ||
html; | ||
let s = '', html; | ||
@@ -187,2 +193,19 @@ if (attributes) { | ||
if (!(opts && opts.allAttributes) && (name==='key' || name==='ref')) continue; | ||
if (opts.jsx) { | ||
if (typeof v!=='string') { | ||
preactPlugin.context = context; | ||
preactPlugin.opts = opts; | ||
v = prettyFormat(v, prettyFormatOpts); | ||
if (~v.indexOf('\n')) { | ||
v = `${indent('\n'+v, indentChar)}\n`; | ||
} | ||
s += indent(`\n${name}={${v}}`, indentChar); | ||
} | ||
else { | ||
s += `\n${indentChar}${name}="${encodeEntities(v)}"`; | ||
} | ||
continue; | ||
} | ||
if (name==='className') { | ||
@@ -195,2 +218,3 @@ if (attributes['class']) continue; | ||
} | ||
if (name==='dangerouslySetInnerHTML') { | ||
@@ -213,4 +237,9 @@ html = v && v.__html; | ||
s += '>'; | ||
// account for >1 multiline attribute | ||
let sub = s.replace(/^\n\s*/, ' '); | ||
if (sub!==s && !~sub.indexOf('\n')) s = sub; | ||
else if (~s.indexOf('\n')) s += '\n'; | ||
s = `<${nodeName}${s}>`; | ||
if (html) { | ||
@@ -227,3 +256,3 @@ // if multiline, indent. | ||
let pieces = [], | ||
hasLarge = false; | ||
hasLarge = ~s.indexOf('\n'); | ||
for (let i=0; i<len; i++) { | ||
@@ -230,0 +259,0 @@ let child = children[i]; |
@@ -232,2 +232,107 @@ import { render, shallowRender } from '../src'; | ||
}); | ||
it('should pass context to grandchildren', () => { | ||
const CONTEXT = { a:'a' }; | ||
const PROPS = { b:'b' }; | ||
class Outer extends Component { | ||
getChildContext() { | ||
return CONTEXT; | ||
} | ||
render(props) { | ||
return <div><Inner {...props} /></div>; | ||
} | ||
} | ||
spy(Outer.prototype, 'getChildContext'); | ||
class Inner extends Component { | ||
render(props, state, context) { | ||
return <div>{ context && context.a }</div>; | ||
} | ||
} | ||
spy(Inner.prototype, 'render'); | ||
render(<Outer />); | ||
expect(Outer.prototype.getChildContext).to.have.been.calledOnce; | ||
expect(Inner.prototype.render).to.have.been.calledWith({}, {}, CONTEXT); | ||
CONTEXT.foo = 'bar'; | ||
render(<Outer {...PROPS} />); | ||
expect(Outer.prototype.getChildContext).to.have.been.calledTwice; | ||
expect(Inner.prototype.render).to.have.been.calledWith(PROPS, {}, CONTEXT); | ||
}); | ||
it('should pass context to direct children', () => { | ||
const CONTEXT = { a:'a' }; | ||
const PROPS = { b:'b' }; | ||
class Outer extends Component { | ||
getChildContext() { | ||
return CONTEXT; | ||
} | ||
render(props) { | ||
return <Inner {...props} />; | ||
} | ||
} | ||
spy(Outer.prototype, 'getChildContext'); | ||
class Inner extends Component { | ||
render(props, state, context) { | ||
return <div>{ context && context.a }</div>; | ||
} | ||
} | ||
spy(Inner.prototype, 'render'); | ||
render(<Outer />); | ||
expect(Outer.prototype.getChildContext).to.have.been.calledOnce; | ||
expect(Inner.prototype.render).to.have.been.calledWith({}, {}, CONTEXT); | ||
CONTEXT.foo = 'bar'; | ||
render(<Outer {...PROPS} />); | ||
expect(Outer.prototype.getChildContext).to.have.been.calledTwice; | ||
expect(Inner.prototype.render).to.have.been.calledWith(PROPS, {}, CONTEXT); | ||
// make sure render() could make use of context.a | ||
expect(Inner.prototype.render).to.have.returned(match({ children:['a'] })); | ||
}); | ||
it('should preserve existing context properties when creating child contexts', () => { | ||
let outerContext = { outer:true }, | ||
innerContext = { inner:true }; | ||
class Outer extends Component { | ||
getChildContext() { | ||
return { outerContext }; | ||
} | ||
render() { | ||
return <div><Inner /></div>; | ||
} | ||
} | ||
class Inner extends Component { | ||
getChildContext() { | ||
return { innerContext }; | ||
} | ||
render() { | ||
return <InnerMost />; | ||
} | ||
} | ||
class InnerMost extends Component { | ||
render() { | ||
return <strong>test</strong>; | ||
} | ||
} | ||
spy(Inner.prototype, 'render'); | ||
spy(InnerMost.prototype, 'render'); | ||
render(<Outer />); | ||
expect(Inner.prototype.render).to.have.been.calledWith({}, {}, { outerContext }); | ||
expect(InnerMost.prototype.render).to.have.been.calledWith({}, {}, { outerContext, innerContext }); | ||
}); | ||
}); | ||
@@ -234,0 +339,0 @@ |
Sorry, the diff of this file is not supported yet
56910
15
1068
2
+ Addedpretty-format@^3.5.1
+ Addedpretty-format@3.8.0(transitive)