diff --git a/.changeset/beige-hounds-enjoy.md b/.changeset/beige-hounds-enjoy.md new file mode 100644 index 00000000..15dbc9f6 --- /dev/null +++ b/.changeset/beige-hounds-enjoy.md @@ -0,0 +1,5 @@ +--- +'preact-render-to-string': patch +--- + +Change style calculation to use a Set rather than Regex diff --git a/.changeset/quiet-toes-carry.md b/.changeset/quiet-toes-carry.md new file mode 100644 index 00000000..445e54d6 --- /dev/null +++ b/.changeset/quiet-toes-carry.md @@ -0,0 +1,5 @@ +--- +'preact-render-to-string': major +--- + +Remove the castin to VNode for `preact/debug`, this is fixed in Preact >= 10.13.0 diff --git a/package-lock.json b/package-lock.json index 9caa5d6d..5d0d99de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,11 +27,11 @@ "lint-staged": "^10.5.3", "microbundle": "^0.15.1", "mocha": "^8.2.1", - "preact": "^10.11.1", + "preact": "^10.13.0", "prettier": "^2.2.1", "sinon": "^9.2.2", "sinon-chai": "^3.5.0", - "typescript": "^4.1.3" + "typescript": "^5.0.0" }, "peerDependencies": { "preact": ">=10" @@ -7176,6 +7176,19 @@ "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true }, + "node_modules/microbundle/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -10805,9 +10818,9 @@ } }, "node_modules/preact": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.1.tgz", - "integrity": "sha512-1Wz5PCRm6Fg+6BTXWJHhX4wRK9MZbZBHuwBqfZlOdVm2NqPe8/rjYpufvYCwJSGb9layyzB2jTTXfpCTynLqFQ==", + "version": "10.13.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.1.tgz", + "integrity": "sha512-KyoXVDU5OqTpG9LXlB3+y639JAGzl8JSBXLn1J9HTSB3gbKcuInga7bZnXLlxmK94ntTs1EFeZp0lrja2AuBYQ==", "dev": true, "funding": { "type": "opencollective", @@ -13099,16 +13112,16 @@ } }, "node_modules/typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -19605,6 +19618,12 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", "dev": true + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true } } }, @@ -22525,9 +22544,9 @@ "dev": true }, "preact": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.1.tgz", - "integrity": "sha512-1Wz5PCRm6Fg+6BTXWJHhX4wRK9MZbZBHuwBqfZlOdVm2NqPe8/rjYpufvYCwJSGb9layyzB2jTTXfpCTynLqFQ==", + "version": "10.13.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.1.tgz", + "integrity": "sha512-KyoXVDU5OqTpG9LXlB3+y639JAGzl8JSBXLn1J9HTSB3gbKcuInga7bZnXLlxmK94ntTs1EFeZp0lrja2AuBYQ==", "dev": true }, "preferred-pm": { @@ -24350,9 +24369,9 @@ "dev": true }, "typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 8472c4a4..2c1e286b 100644 --- a/package.json +++ b/package.json @@ -122,11 +122,11 @@ "microbundle": "^0.15.1", "mocha": "^8.2.1", "baseline-rts": "npm:preact-render-to-string@latest", - "preact": "^10.11.1", + "preact": "^10.13.0", "prettier": "^2.2.1", "sinon": "^9.2.2", "sinon-chai": "^3.5.0", - "typescript": "^4.1.3" + "typescript": "^5.0.0" }, "dependencies": { "pretty-format": "^3.8.0" diff --git a/src/index.js b/src/index.js index 8332afaf..a9309ec2 100644 --- a/src/index.js +++ b/src/index.js @@ -145,15 +145,6 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) { rendered = rendered + _renderToString(child, context, isSvgMode, selectValue, parent); - - if ( - typeof child === 'string' || - typeof child === 'number' || - typeof child === 'bigint' - ) { - // @ts-ignore manually constructing a Text vnode - vnode[i] = h(null, null, child); - } } return rendered; } @@ -338,6 +329,8 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) { } if (UNSAFE_NAME.test(type)) { + // this seems to performs a lot better than throwing + // return ''; throw new Error(`${type} is not a valid HTML tag name in ${s}>`); } diff --git a/src/util.js b/src/util.js index db59ed19..c3a598e1 100644 --- a/src/util.js +++ b/src/util.js @@ -3,7 +3,6 @@ export const UNSAFE_NAME = /[\s\n\\/='"\0<>]/; export const XLINK = /^xlink:?./; // DOM properties that should NOT have "px" added when numeric -const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/; const ENCODED_ENTITIES = /["&<]/; /** @param {string} str */ @@ -50,9 +49,45 @@ export let isLargeString = (s, length, ignoreLines) => String(s).indexOf('<') !== -1; const JS_TO_CSS = {}; -const SUFFIX_CACHE = {}; -const CSS_REGEX = /([A-Z])/g; +const IS_NON_DIMENSIONAL = new Set([ + 'animation-iteration-count', + 'border-image-outset', + 'border-image-slice', + 'border-image-width', + 'box-flex', + 'box-flex-group', + 'box-ordinal-group', + 'column-count', + 'fill-opacity', + 'flex', + 'flex-grow', + 'flex-negative', + 'flex-order', + 'flex-positive', + 'flex-shrink', + 'flood-opacity', + 'font-weight', + 'grid-column', + 'grid-row', + 'line-clamp', + 'line-height', + 'opacity', + 'order', + 'orphans', + 'stop-opacity', + 'stroke-dasharray', + 'stroke-dashoffset', + 'stroke-miterlimit', + 'stroke-opacity', + 'stroke-width', + 'tab-size', + 'widows', + 'z-index', + 'zoom' +]); + +const CSS_REGEX = /[A-Z]/g; // Convert an Object style to a CSSText string export function styleObjToCss(s) { let str = ''; @@ -63,17 +98,15 @@ export function styleObjToCss(s) { prop[0] == '-' ? prop : JS_TO_CSS[prop] || - (JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$1').toLowerCase()); + (JS_TO_CSS[prop] = prop.replace(CSS_REGEX, '-$&').toLowerCase()); let suffix = ';'; - let isNumber = typeof val === 'number'; - if (isNumber && SUFFIX_CACHE[name]) { - suffix = 'px;'; - } else if ( - isNumber && - IS_NON_DIMENSIONAL.test(prop.toLowerCase()) === false + if ( + typeof val === 'number' && + // Exclude custom-attributes + !name.startsWith('--') && + !IS_NON_DIMENSIONAL.has(name) ) { - SUFFIX_CACHE[name] = true; suffix = 'px;'; } str = str + name + ':' + val + suffix; diff --git a/test/render.test.js b/test/render.test.js index 17391c3a..7ab0bcf8 100644 --- a/test/render.test.js +++ b/test/render.test.js @@ -1313,7 +1313,7 @@ describe('render', () => { ); } - expect(render()).to.equal('

P481

P476951

'); + expect(render()).to.equal('

P0-0

P0-1

'); }); }); });