preact-render-to-string
Version:
Render JSX to an HTML string, with support for Preact components.
1 lines • 20.4 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/util.js","../src/index.js"],"sourcesContent":["export const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/;\nexport const UNSAFE_NAME = /[\\s\\n\\\\/='\"\\0<>]/;\nexport const XLINK = /^xlink:?./;\n\n// DOM properties that should NOT have \"px\" added when numeric\nconst ENCODED_ENTITIES = /[\"&<]/;\n\n/** @param {string} str */\nexport function encodeEntities(str) {\n\t// Skip all work for strings with no entities needing encoding:\n\tif (str.length === 0 || ENCODED_ENTITIES.test(str) === false) return str;\n\n\tlet last = 0,\n\t\ti = 0,\n\t\tout = '',\n\t\tch = '';\n\n\t// Seek forward in str until the next entity char:\n\tfor (; i < str.length; i++) {\n\t\tswitch (str.charCodeAt(i)) {\n\t\t\tcase 34:\n\t\t\t\tch = '"';\n\t\t\t\tbreak;\n\t\t\tcase 38:\n\t\t\t\tch = '&';\n\t\t\t\tbreak;\n\t\t\tcase 60:\n\t\t\t\tch = '<';\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontinue;\n\t\t}\n\t\t// Append skipped/buffered characters and the encoded entity:\n\t\tif (i !== last) out += str.slice(last, i);\n\t\tout += ch;\n\t\t// Start the next seek/buffer after the entity's offset:\n\t\tlast = i + 1;\n\t}\n\tif (i !== last) out += str.slice(last, i);\n\treturn out;\n}\n\nexport let indent = (s, char) =>\n\tString(s).replace(/(\\n+)/g, '$1' + (char || '\\t'));\n\nexport let isLargeString = (s, length, ignoreLines) =>\n\tString(s).length > (length || 40) ||\n\t(!ignoreLines && String(s).indexOf('\\n') !== -1) ||\n\tString(s).indexOf('<') !== -1;\n\nconst JS_TO_CSS = {};\n\nconst IS_NON_DIMENSIONAL = new Set([\n\t'animation-iteration-count',\n\t'border-image-outset',\n\t'border-image-slice',\n\t'border-image-width',\n\t'box-flex',\n\t'box-flex-group',\n\t'box-ordinal-group',\n\t'column-count',\n\t'fill-opacity',\n\t'flex',\n\t'flex-grow',\n\t'flex-negative',\n\t'flex-order',\n\t'flex-positive',\n\t'flex-shrink',\n\t'flood-opacity',\n\t'font-weight',\n\t'grid-column',\n\t'grid-row',\n\t'line-clamp',\n\t'line-height',\n\t'opacity',\n\t'order',\n\t'orphans',\n\t'stop-opacity',\n\t'stroke-dasharray',\n\t'stroke-dashoffset',\n\t'stroke-miterlimit',\n\t'stroke-opacity',\n\t'stroke-width',\n\t'tab-size',\n\t'widows',\n\t'z-index',\n\t'zoom'\n]);\n\nconst CSS_REGEX = /[A-Z]/g;\n// Convert an Object style to a CSSText string\nexport function styleObjToCss(s) {\n\tlet str = '';\n\tfor (let prop in s) {\n\t\tlet val = s[prop];\n\t\tif (val != null && val !== '') {\n\t\t\tconst name =\n\t\t\t\tprop[0] == '-'\n\t\t\t\t\t? prop\n\t\t\t\t\t: JS_TO_CSS[prop] ||\n\t\t\t\t\t (JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$&').toLowerCase());\n\n\t\t\tlet suffix = ';';\n\t\t\tif (\n\t\t\t\ttypeof val === 'number' &&\n\t\t\t\t// Exclude custom-attributes\n\t\t\t\t!name.startsWith('--') &&\n\t\t\t\t!IS_NON_DIMENSIONAL.has(name)\n\t\t\t) {\n\t\t\t\tsuffix = 'px;';\n\t\t\t}\n\t\t\tstr = str + name + ':' + val + suffix;\n\t\t}\n\t}\n\treturn str || undefined;\n}\n\n/**\n * Get flattened children from the children prop\n * @param {Array} accumulator\n * @param {any} children A `props.children` opaque object.\n * @returns {Array} accumulator\n * @private\n */\nexport function getChildren(accumulator, children) {\n\tif (Array.isArray(children)) {\n\t\tchildren.reduce(getChildren, accumulator);\n\t} else if (children != null && children !== false) {\n\t\taccumulator.push(children);\n\t}\n\treturn accumulator;\n}\n\nfunction markAsDirty() {\n\tthis.__d = true;\n}\n\nexport function createComponent(vnode, context) {\n\treturn {\n\t\t__v: vnode,\n\t\tcontext,\n\t\tprops: vnode.props,\n\t\t// silently drop state updates\n\t\tsetState: markAsDirty,\n\t\tforceUpdate: markAsDirty,\n\t\t__d: true,\n\t\t// hooks\n\t\t__h: []\n\t};\n}\n","import { encodeEntities, styleObjToCss, UNSAFE_NAME, XLINK } from './util';\nimport { options, h, Fragment } from 'preact';\nimport {\n\tCHILDREN,\n\tCOMMIT,\n\tCOMPONENT,\n\tDIFF,\n\tDIFFED,\n\tDIRTY,\n\tNEXT_STATE,\n\tPARENT,\n\tRENDER,\n\tSKIP_EFFECTS,\n\tVNODE\n} from './constants';\n\n/** @typedef {import('preact').VNode} VNode */\n\nconst EMPTY_ARR = [];\nconst isArray = Array.isArray;\nconst assign = Object.assign;\n\n// Global state for the current render pass\nlet beforeDiff, afterDiff, renderHook, ummountHook;\n\n/**\n * Render Preact JSX + Components to an HTML string.\n * @param {VNode} vnode\tJSX Element / VNode to render\n * @param {Object} [context={}] Initial root context object\n * @returns {string} serialized HTML\n */\nexport function renderToString(vnode, context) {\n\t// Performance optimization: `renderToString` is synchronous and we\n\t// therefore don't execute any effects. To do that we pass an empty\n\t// array to `options._commit` (`__c`). But we can go one step further\n\t// and avoid a lot of dirty checks and allocations by setting\n\t// `options._skipEffects` (`__s`) too.\n\tconst previousSkipEffects = options[SKIP_EFFECTS];\n\toptions[SKIP_EFFECTS] = true;\n\n\t// store options hooks once before each synchronous render call\n\tbeforeDiff = options[DIFF];\n\tafterDiff = options[DIFFED];\n\trenderHook = options[RENDER];\n\tummountHook = options.unmount;\n\n\tconst parent = h(Fragment, null);\n\tparent[CHILDREN] = [vnode];\n\n\ttry {\n\t\treturn _renderToString(\n\t\t\tvnode,\n\t\t\tcontext || EMPTY_OBJ,\n\t\t\tfalse,\n\t\t\tundefined,\n\t\t\tparent\n\t\t);\n\t} finally {\n\t\t// options._commit, we don't schedule any effects in this library right now,\n\t\t// so we can pass an empty queue to this hook.\n\t\tif (options[COMMIT]) options[COMMIT](vnode, EMPTY_ARR);\n\t\toptions[SKIP_EFFECTS] = previousSkipEffects;\n\t\tEMPTY_ARR.length = 0;\n\t}\n}\n\n// Installed as setState/forceUpdate for function components\nfunction markAsDirty() {\n\tthis.__d = true;\n}\n\nconst EMPTY_OBJ = {};\n\n/**\n * @param {VNode} vnode\n * @param {Record<string, unknown>} context\n */\nfunction renderClassComponent(vnode, context) {\n\tlet type = /** @type {import(\"preact\").ComponentClass<typeof vnode.props>} */ (vnode.type);\n\n\tlet c = new type(vnode.props, context);\n\n\tvnode[COMPONENT] = c;\n\tc[VNODE] = vnode;\n\n\tc.props = vnode.props;\n\tc.context = context;\n\t// turn off stateful re-rendering:\n\tc[DIRTY] = true;\n\n\tif (c.state == null) c.state = EMPTY_OBJ;\n\n\tif (c[NEXT_STATE] == null) {\n\t\tc[NEXT_STATE] = c.state;\n\t}\n\n\tif (type.getDerivedStateFromProps) {\n\t\tc.state = assign(\n\t\t\t{},\n\t\t\tc.state,\n\t\t\ttype.getDerivedStateFromProps(c.props, c.state)\n\t\t);\n\t} else if (c.componentWillMount) {\n\t\tc.componentWillMount();\n\n\t\t// If the user called setState in cWM we need to flush pending,\n\t\t// state updates. This is the same behaviour in React.\n\t\tc.state = c[NEXT_STATE] !== c.state ? c[NEXT_STATE] : c.state;\n\t}\n\n\tif (renderHook) renderHook(vnode);\n\n\treturn c.render(c.props, c.state, context);\n}\n\n/**\n * Recursively render VNodes to HTML.\n * @param {VNode|any} vnode\n * @param {any} context\n * @param {boolean} isSvgMode\n * @param {any} selectValue\n * @param {VNode} parent\n * @returns {string}\n */\nfunction _renderToString(vnode, context, isSvgMode, selectValue, parent) {\n\t// Ignore non-rendered VNodes/values\n\tif (vnode == null || vnode === true || vnode === false || vnode === '') {\n\t\treturn '';\n\t}\n\n\t// Text VNodes: escape as HTML\n\tif (typeof vnode !== 'object') {\n\t\tif (typeof vnode === 'function') return '';\n\t\treturn encodeEntities(vnode + '');\n\t}\n\n\t// Recurse into children / Arrays\n\tif (isArray(vnode)) {\n\t\tlet rendered = '';\n\t\tparent[CHILDREN] = vnode;\n\t\tfor (let i = 0; i < vnode.length; i++) {\n\t\t\tlet child = vnode[i];\n\t\t\tif (child == null || typeof child === 'boolean') continue;\n\n\t\t\trendered =\n\t\t\t\trendered +\n\t\t\t\t_renderToString(child, context, isSvgMode, selectValue, parent);\n\t\t}\n\t\treturn rendered;\n\t}\n\n\t// VNodes have {constructor:undefined} to prevent JSON injection:\n\tif (vnode.constructor !== undefined) return '';\n\n\tvnode[PARENT] = parent;\n\tif (beforeDiff) beforeDiff(vnode);\n\n\tlet type = vnode.type,\n\t\tprops = vnode.props,\n\t\tcctx = context,\n\t\tcontextType,\n\t\trendered,\n\t\tcomponent;\n\n\t// Invoke rendering on Components\n\tif (typeof type === 'function') {\n\t\tif (type === Fragment) {\n\t\t\trendered = props.children;\n\t\t} else {\n\t\t\tcontextType = type.contextType;\n\t\t\tif (contextType != null) {\n\t\t\t\tlet provider = context[contextType.__c];\n\t\t\t\tcctx = provider ? provider.props.value : contextType.__;\n\t\t\t}\n\n\t\t\tif (type.prototype && typeof type.prototype.render === 'function') {\n\t\t\t\trendered = /**#__NOINLINE__**/ renderClassComponent(vnode, cctx);\n\t\t\t\tcomponent = vnode[COMPONENT];\n\t\t\t} else {\n\t\t\t\tcomponent = {\n\t\t\t\t\t__v: vnode,\n\t\t\t\t\tprops,\n\t\t\t\t\tcontext: cctx,\n\t\t\t\t\t// silently drop state updates\n\t\t\t\t\tsetState: markAsDirty,\n\t\t\t\t\tforceUpdate: markAsDirty,\n\t\t\t\t\t__d: true,\n\t\t\t\t\t// hooks\n\t\t\t\t\t__h: []\n\t\t\t\t};\n\t\t\t\tvnode[COMPONENT] = component;\n\n\t\t\t\t// If a hook invokes setState() to invalidate the component during rendering,\n\t\t\t\t// re-render it up to 25 times to allow \"settling\" of memoized states.\n\t\t\t\t// Note:\n\t\t\t\t// This will need to be updated for Preact 11 to use internal.flags rather than component._dirty:\n\t\t\t\t// https://github.com/preactjs/preact/blob/d4ca6fdb19bc715e49fd144e69f7296b2f4daa40/src/diff/component.js#L35-L44\n\t\t\t\tlet count = 0;\n\t\t\t\twhile (component[DIRTY] && count++ < 25) {\n\t\t\t\t\tcomponent[DIRTY] = false;\n\n\t\t\t\t\tif (renderHook) renderHook(vnode);\n\n\t\t\t\t\trendered = type.call(component, props, cctx);\n\t\t\t\t}\n\t\t\t\tcomponent[DIRTY] = true;\n\t\t\t}\n\n\t\t\tif (component.getChildContext != null) {\n\t\t\t\tcontext = assign({}, context, component.getChildContext());\n\t\t\t}\n\t\t}\n\n\t\t// When a component returns a Fragment node we flatten it in core, so we\n\t\t// need to mirror that logic here too\n\t\tlet isTopLevelFragment =\n\t\t\trendered != null && rendered.type === Fragment && rendered.key == null;\n\t\trendered = isTopLevelFragment ? rendered.props.children : rendered;\n\n\t\t// Recurse into children before invoking the after-diff hook\n\t\tconst str = _renderToString(\n\t\t\trendered,\n\t\t\tcontext,\n\t\t\tisSvgMode,\n\t\t\tselectValue,\n\t\t\tvnode\n\t\t);\n\t\tif (afterDiff) afterDiff(vnode);\n\t\tvnode[PARENT] = undefined;\n\n\t\tif (ummountHook) ummountHook(vnode);\n\n\t\treturn str;\n\t}\n\n\t// Serialize Element VNodes to HTML\n\tlet s = '<' + type,\n\t\thtml = '',\n\t\tchildren;\n\n\tfor (let name in props) {\n\t\tlet v = props[name];\n\n\t\tswitch (name) {\n\t\t\tcase 'children':\n\t\t\t\tchildren = v;\n\t\t\t\tcontinue;\n\n\t\t\t// VDOM-specific props\n\t\t\tcase 'key':\n\t\t\tcase 'ref':\n\t\t\tcase '__self':\n\t\t\tcase '__source':\n\t\t\t\tcontinue;\n\n\t\t\t// prefer for/class over htmlFor/className\n\t\t\tcase 'htmlFor':\n\t\t\t\tif ('for' in props) continue;\n\t\t\t\tname = 'for';\n\t\t\t\tbreak;\n\t\t\tcase 'className':\n\t\t\t\tif ('class' in props) continue;\n\t\t\t\tname = 'class';\n\t\t\t\tbreak;\n\n\t\t\t// Form element reflected properties\n\t\t\tcase 'defaultChecked':\n\t\t\t\tname = 'checked';\n\t\t\t\tbreak;\n\t\t\tcase 'defaultSelected':\n\t\t\t\tname = 'selected';\n\t\t\t\tbreak;\n\n\t\t\t// Special value attribute handling\n\t\t\tcase 'defaultValue':\n\t\t\tcase 'value':\n\t\t\t\tname = 'value';\n\t\t\t\tswitch (type) {\n\t\t\t\t\t// <textarea value=\"a&b\"> --> <textarea>a&b</textarea>\n\t\t\t\t\tcase 'textarea':\n\t\t\t\t\t\tchildren = v;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t// <select value> is serialized as a selected attribute on the matching option child\n\t\t\t\t\tcase 'select':\n\t\t\t\t\t\tselectValue = v;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t// Add a selected attribute to <option> if its value matches the parent <select> value\n\t\t\t\t\tcase 'option':\n\t\t\t\t\t\tif (selectValue == v && !('selected' in props)) {\n\t\t\t\t\t\t\ts = s + ' selected';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'dangerouslySetInnerHTML':\n\t\t\t\thtml = v && v.__html;\n\t\t\t\tcontinue;\n\n\t\t\t// serialize object styles to a CSS string\n\t\t\tcase 'style':\n\t\t\t\tif (typeof v === 'object') {\n\t\t\t\t\tv = styleObjToCss(v);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault: {\n\t\t\t\tif (isSvgMode && XLINK.test(name)) {\n\t\t\t\t\tname = name.toLowerCase().replace(XLINK_REPLACE_REGEX, 'xlink:');\n\t\t\t\t} else if (UNSAFE_NAME.test(name)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if ((name[4] === '-' || name === 'draggable') && v != null) {\n\t\t\t\t\t// serialize boolean aria-xyz or draggable attribute values as strings\n\t\t\t\t\t// `draggable` is an enumerated attribute and not Boolean. A value of `true` or `false` is mandatory\n\t\t\t\t\t// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable\n\t\t\t\t\tv += '';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// write this attribute to the buffer\n\t\tif (v != null && v !== false && typeof v !== 'function') {\n\t\t\tif (v === true || v === '') {\n\t\t\t\ts = s + ' ' + name;\n\t\t\t} else {\n\t\t\t\ts = s + ' ' + name + '=\"' + encodeEntities(v + '') + '\"';\n\t\t\t}\n\t\t}\n\t}\n\n\tif (UNSAFE_NAME.test(type)) {\n\t\t// this seems to performs a lot better than throwing\n\t\t// return '<!-- -->';\n\t\tthrow new Error(`${type} is not a valid HTML tag name in ${s}>`);\n\t}\n\n\tif (html) {\n\t\t// dangerouslySetInnerHTML defined this node's contents\n\t} else if (typeof children === 'string') {\n\t\t// single text child\n\t\thtml = encodeEntities(children);\n\t} else if (children != null && children !== false && children !== true) {\n\t\t// recurse into this element VNode's children\n\t\tlet childSvgMode =\n\t\t\ttype === 'svg' || (type !== 'foreignObject' && isSvgMode);\n\t\thtml = _renderToString(children, context, childSvgMode, selectValue, vnode);\n\t}\n\n\tif (afterDiff) afterDiff(vnode);\n\tvnode[PARENT] = undefined;\n\tif (ummountHook) ummountHook(vnode);\n\n\t// Emit self-closing tag for empty void elements:\n\tif (!html && SELF_CLOSING.has(type)) {\n\t\treturn s + '/>';\n\t}\n\n\treturn s + '>' + html + '</' + type + '>';\n}\n\nconst XLINK_REPLACE_REGEX = /^xlink:?/;\nconst SELF_CLOSING = new Set([\n\t'area',\n\t'base',\n\t'br',\n\t'col',\n\t'command',\n\t'embed',\n\t'hr',\n\t'img',\n\t'input',\n\t'keygen',\n\t'link',\n\t'meta',\n\t'param',\n\t'source',\n\t'track',\n\t'wbr'\n]);\n\nexport default renderToString;\nexport const render = renderToString;\nexport const renderToStaticMarkup = renderToString;\n"],"names":["UNSAFE_NAME","XLINK","ENCODED_ENTITIES","encodeEntities","str","length","test","last","i","out","ch","charCodeAt","slice","JS_TO_CSS","IS_NON_DIMENSIONAL","Set","CSS_REGEX","styleObjToCss","s","prop","val","name","replace","toLowerCase","suffix","startsWith","has","undefined","EMPTY_ARR","isArray","Array","assign","Object","beforeDiff","afterDiff","renderHook","ummountHook","renderToString","vnode","context","previousSkipEffects","options","unmount","parent","h","Fragment","_renderToString","EMPTY_OBJ","markAsDirty","this","__d","renderClassComponent","type","c","props","state","getDerivedStateFromProps","componentWillMount","render","isSvgMode","selectValue","rendered","child","constructor","contextType","component","cctx","children","provider","__c","value","__","prototype","__v","setState","forceUpdate","__h","count","call","getChildContext","key","html","v","__html","XLINK_REPLACE_REGEX","Error","SELF_CLOSING","renderToStaticMarkup"],"mappings":"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"}