diff --git a/.changeset/strange-dodos-happen.md b/.changeset/strange-dodos-happen.md new file mode 100644 index 000000000..aebea2bda --- /dev/null +++ b/.changeset/strange-dodos-happen.md @@ -0,0 +1,5 @@ +--- +'@react-pdf/render': major +--- + +refactor: remove ramda from render package diff --git a/packages/render/package.json b/packages/render/package.json index e443e6329..e34f9cc89 100644 --- a/packages/render/package.json +++ b/packages/render/package.json @@ -25,7 +25,6 @@ "color-string": "^1.5.3", "normalize-svg-path": "^1.1.0", "parse-svg-path": "^0.1.2", - "ramda": "^0.26.1", "svg-arc-to-cubic-bezier": "^3.2.0" }, "files": [ diff --git a/packages/render/src/index.js b/packages/render/src/index.js index 9297abecf..22585b1e4 100644 --- a/packages/render/src/index.js +++ b/packages/render/src/index.js @@ -1,14 +1,12 @@ import renderNode from './primitives/renderNode'; import addMetadata from './operations/addMetadata'; -const renderDocument = ctx => doc => { +const render = (ctx, doc) => { const pages = doc.children || []; - pages.forEach(renderNode(ctx)); -}; -const render = (ctx, doc) => { - addMetadata(ctx)(doc); - renderDocument(ctx)(doc); + addMetadata(ctx, doc); + + pages.forEach(page => renderNode(ctx, page)); ctx.end(); diff --git a/packages/render/src/operations/addMetadata.js b/packages/render/src/operations/addMetadata.js index b26aa7d4b..13294e5bf 100644 --- a/packages/render/src/operations/addMetadata.js +++ b/packages/render/src/operations/addMetadata.js @@ -1,10 +1,5 @@ /* eslint-disable no-param-reassign */ -import * as R from 'ramda'; - -const getDocumentProp = target => (or, prop) => - R.pathOr(or, ['props', prop], target); - const setPDFMetadata = target => (key, value) => { if (value) target.info[key] = value; }; @@ -16,15 +11,15 @@ const setPDFMetadata = target => (key, value) => { * @param {Object} doc document root */ const addMetadata = (ctx, doc) => { - const getProp = getDocumentProp(doc); const setProp = setPDFMetadata(ctx); - const title = getProp(null, 'title'); - const author = getProp(null, 'author'); - const subject = getProp(null, 'subject'); - const keywords = getProp(null, 'keywords'); - const creator = getProp('react-pdf', 'creator'); - const producer = getProp('react-pdf', 'producer'); + const props = doc.props || {}; + const title = props.title || null; + const author = props.author || null; + const subject = props.subject || null; + const keywords = props.keywords || null; + const creator = props.creator || 'react-pdf'; + const producer = props.producer || 'react-pdf'; setProp('Title', title); setProp('Author', author); @@ -32,8 +27,6 @@ const addMetadata = (ctx, doc) => { setProp('Keywords', keywords); setProp('Creator', creator); setProp('Producer', producer); - - return doc; }; -export default R.curryN(2, addMetadata); +export default addMetadata; diff --git a/packages/render/src/operations/clipNode.js b/packages/render/src/operations/clipNode.js index 6343f718c..ffeeb38c9 100644 --- a/packages/render/src/operations/clipNode.js +++ b/packages/render/src/operations/clipNode.js @@ -1,11 +1,9 @@ -import * as R from 'ramda'; - // This constant is used to approximate a symmetrical arc using a cubic // Bezier curve. const KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0); const clipNode = (ctx, node) => { - if (!node.style) return node; + if (!node.style) return; const { top, left, width, height } = node.box; @@ -67,8 +65,6 @@ const clipNode = (ctx, node) => { ctx.bezierCurveTo(left, top + ctl, left + ctl, top, left + rtl, top); ctx.closePath(); ctx.clip(); - - return node; }; -export default R.curryN(2, clipNode); +export default clipNode; diff --git a/packages/render/src/operations/restore.js b/packages/render/src/operations/restore.js deleted file mode 100644 index 0e2bfcea8..000000000 --- a/packages/render/src/operations/restore.js +++ /dev/null @@ -1,8 +0,0 @@ -import * as R from 'ramda'; - -const restore = (ctx, node) => { - ctx.restore(); - return node; -}; - -export default R.curryN(2, restore); diff --git a/packages/render/src/operations/save.js b/packages/render/src/operations/save.js deleted file mode 100644 index 794e4e1fb..000000000 --- a/packages/render/src/operations/save.js +++ /dev/null @@ -1,8 +0,0 @@ -import * as R from 'ramda'; - -const save = (ctx, node) => { - ctx.save(); - return node; -}; - -export default R.curryN(2, save); diff --git a/packages/render/src/operations/setDestination.js b/packages/render/src/operations/setDestination.js index d8da048e5..2ec1da909 100644 --- a/packages/render/src/operations/setDestination.js +++ b/packages/render/src/operations/setDestination.js @@ -1,11 +1,7 @@ -import * as R from 'ramda'; - const setDestination = (ctx, node) => { if (node.props?.id) { ctx.addNamedDestination(node.props.id, 'XYZ', null, node.box.top, null); } +}; - return node; -} - -export default R.curryN(2, setDestination); +export default setDestination; diff --git a/packages/render/src/operations/setLink.js b/packages/render/src/operations/setLink.js index 349955c6e..8c323ef06 100644 --- a/packages/render/src/operations/setLink.js +++ b/packages/render/src/operations/setLink.js @@ -1,17 +1,9 @@ -import * as R from 'ramda'; - -const DEST_REGEXP = /^#.+/; - -const isSrcId = R.test(DEST_REGEXP); - -const getSource = node => { - const props = node.props || {}; - return props.src || props.href; -}; +const isSrcId = value => /^#.+/.test(value); const setLink = (ctx, node) => { + const props = node.props || {}; const { top, left, width, height } = node.box; - const src = getSource(node); + const src = props.src || props.href; if (src) { const isId = isSrcId(src); @@ -20,8 +12,6 @@ const setLink = (ctx, node) => { ctx[method](left, top, width, height, value); } - - return node; }; -export default R.curryN(2, setLink); +export default setLink; diff --git a/packages/render/src/operations/transform.js b/packages/render/src/operations/transform.js index aa498e712..7109fe2fe 100644 --- a/packages/render/src/operations/transform.js +++ b/packages/render/src/operations/transform.js @@ -1,5 +1,3 @@ -import * as R from 'ramda'; - // TODO: Implement using only matrices to support skew and even more operations than css. const applySingleTransformation = (ctx, transform, origin) => { @@ -36,7 +34,7 @@ const applySingleTransformation = (ctx, transform, origin) => { }; const applyTransformations = (ctx, node) => { - if (!node.origin) return node; + if (!node.origin) return; const origin = [node.origin.left, node.origin.top]; const operations = node.style?.transform || node.props?.transform || []; @@ -44,8 +42,6 @@ const applyTransformations = (ctx, node) => { operations.forEach(operation => { applySingleTransformation(ctx, operation, origin); }); - - return node; }; -export default R.curryN(2, applyTransformations); +export default applyTransformations; diff --git a/packages/render/src/primitives/renderBackground.js b/packages/render/src/primitives/renderBackground.js index b78825f07..9efee4036 100644 --- a/packages/render/src/primitives/renderBackground.js +++ b/packages/render/src/primitives/renderBackground.js @@ -1,38 +1,29 @@ -import * as R from 'ramda'; - -import save from '../operations/save'; -import restore from '../operations/restore'; import clipNode from '../operations/clipNode'; import parseColor from '../utils/parseColor'; +import isNil from '../../../fns/isNil'; const drawBackground = (ctx, node) => { - if (node.box && node.style.backgroundColor) { - const { top, left, width, height } = node.box; - const color = parseColor(node.style.backgroundColor); - const nodeOpacity = R.isNil(node.style?.opacity) ? 1 : node.style.opacity; - const opacity = Math.min(color.opacity, nodeOpacity); - - ctx - .fillOpacity(opacity) - .fillColor(color.value) - .rect(left, top, width, height) - .fill(); - } - - return node; + const { top, left, width, height } = node.box; + const color = parseColor(node.style.backgroundColor); + const nodeOpacity = isNil(node.style?.opacity) ? 1 : node.style.opacity; + const opacity = Math.min(color.opacity, nodeOpacity); + + ctx + .fillOpacity(opacity) + .fillColor(color.value) + .rect(left, top, width, height) + .fill(); }; const renderBackground = (ctx, node) => { const hasBackground = !!node.box && !!node.style?.backgroundColor; if (hasBackground) { - save(ctx, node); + ctx.save(); clipNode(ctx, node); drawBackground(ctx, node); - restore(ctx, node); + ctx.restore(); } - - return node; }; -export default R.curryN(2, renderBackground); +export default renderBackground; diff --git a/packages/render/src/primitives/renderBorders.js b/packages/render/src/primitives/renderBorders.js index e09c1c599..7f0d75aa5 100644 --- a/packages/render/src/primitives/renderBorders.js +++ b/packages/render/src/primitives/renderBorders.js @@ -1,5 +1,3 @@ -import * as R from 'ramda'; - // Ref: https://www.w3.org/TR/css-backgrounds-3/#borders // This constant is used to approximate a symmetrical arc using a cubic Bezier curve. @@ -604,7 +602,7 @@ const shouldRenderBorders = node => node.box.borderLeftWidth); const renderBorders = (ctx, node) => { - if (!shouldRenderBorders(node)) return node; + if (!shouldRenderBorders(node)) return; const { width, @@ -687,8 +685,6 @@ const renderBorders = (ctx, node) => { } ctx.restore(); - - return node; }; -export default R.curryN(2, renderBorders); +export default renderBorders; diff --git a/packages/render/src/primitives/renderCanvas.js b/packages/render/src/primitives/renderCanvas.js index f85de7456..64fe10180 100644 --- a/packages/render/src/primitives/renderCanvas.js +++ b/packages/render/src/primitives/renderCanvas.js @@ -1,5 +1,3 @@ -import * as R from 'ramda'; - const availableMethods = [ 'dash', 'clip', @@ -52,15 +50,13 @@ const painter = ctx => { return p; }; -const defaultsZero = R.propOr(0); - const renderCanvas = (ctx, node) => { const { top, left, width, height } = node.box; - const paddingTop = defaultsZero('paddingTop', node.box); - const paddingLeft = defaultsZero('paddingLeft', node.box); - const paddingRight = defaultsZero('paddingRight', node.box); - const paddingBottom = defaultsZero('paddingBottom', node.box); + const paddingTop = node.box.paddingTop || 0; + const paddingLeft = node.box.paddingLeft || 0; + const paddingRight = node.box.paddingRight || 0; + const paddingBottom = node.box.paddingBottom || 0; const availableWidth = width - paddingLeft - paddingRight; const availableHeight = height - paddingTop - paddingBottom; @@ -78,8 +74,6 @@ const renderCanvas = (ctx, node) => { } ctx.restore(); - - return node; }; -export default R.curryN(2, renderCanvas); +export default renderCanvas; diff --git a/packages/render/src/primitives/renderCircle.js b/packages/render/src/primitives/renderCircle.js index 213ac3130..dbdfb8ffd 100644 --- a/packages/render/src/primitives/renderCircle.js +++ b/packages/render/src/primitives/renderCircle.js @@ -1,17 +1,11 @@ -import * as R from 'ramda'; - import { drawEllipse } from './renderEllipse'; -const getProp = (p, v) => R.path(['props', p], v); - const renderCircle = (ctx, node) => { - const cx = getProp('cx', node); - const cy = getProp('cy', node); - const r = getProp('r', node); + const cx = node.props?.cx; + const cy = node.props?.cy; + const r = node.props?.r; drawEllipse(ctx, cx, cy, r, r); - - return node; }; -export default R.curryN(2, renderCircle); +export default renderCircle; diff --git a/packages/render/src/primitives/renderDebug.js b/packages/render/src/primitives/renderDebug.js index 6797d4470..f29716012 100644 --- a/packages/render/src/primitives/renderDebug.js +++ b/packages/render/src/primitives/renderDebug.js @@ -1,17 +1,10 @@ -import * as R from 'ramda'; - -import save from '../operations/save'; -import restore from '../operations/restore'; - const CONTENT_COLOR = '#a1c6e7'; const PADDING_COLOR = '#c4deb9'; const MARGIN_COLOR = '#f8cca1'; -const shouldDebug = R.pathEq(['props', 'debug'], true); - // TODO: Draw debug boxes using clipping to enhance quality -const debugContent = ctx => node => { +const debugContent = (ctx, node) => { const { left, top, @@ -37,11 +30,9 @@ const debugContent = ctx => node => { height - paddingTop - paddingBottom - borderTopWidth - borderBottomWidth, ) .fill(); - - return node; }; -const debugPadding = ctx => node => { +const debugPadding = (ctx, node) => { const { left, top, @@ -98,7 +89,6 @@ const debugPadding = ctx => node => { paddingBottom, ) .fill(); - return node; }; const getMargin = box => { @@ -115,7 +105,7 @@ const getMargin = box => { }; }; -const debugMargin = ctx => node => { +const debugMargin = (ctx, node) => { const { left, top, width, height } = node.box; const { marginLeft = 0, @@ -150,11 +140,9 @@ const debugMargin = ctx => node => { // Margin bottom ctx.rect(left, top + height, width, marginBottom).fill(); - - return node; }; -const debugText = ctx => node => { +const debugText = (ctx, node) => { const { left, top, width, height } = node.box; const { marginLeft = 0, @@ -175,11 +163,9 @@ const debugText = ctx => node => { left - marginLeft, Math.max(top - marginTop - 4, 1), ); - - return node; }; -const debugOrigin = ctx => node => { +const debugOrigin = (ctx, node) => { if (node.origin) { ctx .circle(node.origin.left, node.origin.top, 3) @@ -187,24 +173,20 @@ const debugOrigin = ctx => node => { .circle(node.origin.left, node.origin.top, 5) .stroke('red'); } - - return node; }; -const renderDebug = ctx => - R.tap( - R.when( - shouldDebug, - R.compose( - restore(ctx), - debugOrigin(ctx), - debugText(ctx), - debugMargin(ctx), - debugPadding(ctx), - debugContent(ctx), - save(ctx), - ), - ), - ); +const renderDebug = (ctx, node) => { + if (!node.props.debug) return; + + ctx.save(); + + debugContent(ctx, node); + debugPadding(ctx, node); + debugMargin(ctx, node); + debugText(ctx, node); + debugOrigin(ctx, node); + + ctx.restore(); +}; export default renderDebug; diff --git a/packages/render/src/primitives/renderEllipse.js b/packages/render/src/primitives/renderEllipse.js index 72aabe96b..4319f9067 100644 --- a/packages/render/src/primitives/renderEllipse.js +++ b/packages/render/src/primitives/renderEllipse.js @@ -1,9 +1,5 @@ -import * as R from 'ramda'; - const KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0); -const getProp = (p, v) => R.path(['props', p], v); - export const drawEllipse = (ctx, cx, cy, rx, ry) => { const x = cx - rx; const y = cy - ry; @@ -23,14 +19,9 @@ export const drawEllipse = (ctx, cx, cy, rx, ry) => { }; const renderEllipse = (ctx, node) => { - const cx = getProp('cx', node); - const cy = getProp('cy', node); - const rx = getProp('rx', node); - const ry = getProp('ry', node); + const { cx, cy, rx, ry } = node.props || {}; drawEllipse(ctx, cx, cy, rx, ry); - - return node; }; -export default R.curryN(2, renderEllipse); +export default renderEllipse; diff --git a/packages/render/src/primitives/renderGroup.js b/packages/render/src/primitives/renderGroup.js index ef9bcba5a..016f22395 100644 --- a/packages/render/src/primitives/renderGroup.js +++ b/packages/render/src/primitives/renderGroup.js @@ -1,5 +1,5 @@ -import * as R from 'ramda'; - -const renderGroup = () => R.identity; +const renderGroup = () => { + // noop +}; export default renderGroup; diff --git a/packages/render/src/primitives/renderImage.js b/packages/render/src/primitives/renderImage.js index 5e1286398..004f75b46 100644 --- a/packages/render/src/primitives/renderImage.js +++ b/packages/render/src/primitives/renderImage.js @@ -1,11 +1,7 @@ -import * as R from 'ramda'; - -import save from '../operations/save'; -import restore from '../operations/restore'; import clipNode from '../operations/clipNode'; import resolveObjectFit from '../utils/resolveObjectFit'; -const drawImage = ctx => node => { +const drawImage = (ctx, node) => { const { left, top } = node.box; const opacity = node.style?.opacity; const objectFit = node.style?.objectFit; @@ -45,14 +41,15 @@ const drawImage = ctx => node => { ); } } - - return node; }; const renderImage = (ctx, node) => { - R.compose(restore(ctx), drawImage(ctx), clipNode(ctx), save(ctx))(node); + ctx.save(); + + clipNode(ctx, node); + drawImage(ctx, node); - return node; + ctx.restore(); }; -export default R.curryN(2, renderImage); +export default renderImage; diff --git a/packages/render/src/primitives/renderLine.js b/packages/render/src/primitives/renderLine.js index e1e025eda..0fb54442a 100644 --- a/packages/render/src/primitives/renderLine.js +++ b/packages/render/src/primitives/renderLine.js @@ -1,17 +1,8 @@ -import * as R from 'ramda'; - -const getProp = (p, v) => R.path(['props', p], v); - -const renderLine = ctx => node => { - const x1 = getProp('x1', node); - const y1 = getProp('y1', node); - const x2 = getProp('x2', node); - const y2 = getProp('y2', node); +const renderLine = (ctx, node) => { + const { x1, x2, y1, y2 } = node.props || {}; ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); - - return node; }; export default renderLine; diff --git a/packages/render/src/primitives/renderNode.js b/packages/render/src/primitives/renderNode.js index 11d911ef2..d2415c892 100644 --- a/packages/render/src/primitives/renderNode.js +++ b/packages/render/src/primitives/renderNode.js @@ -1,5 +1,4 @@ -import * as R from 'ramda'; - +import * as P from '@react-pdf/primitives'; import renderSvg from './renderSvg'; import renderText from './renderText'; import renderPage from './renderPage'; @@ -9,62 +8,61 @@ import renderDebug from './renderDebug'; import renderCanvas from './renderCanvas'; import renderBorders from './renderBorders'; import renderBackground from './renderBackground'; -import isSvg from '../utils/isSvg'; -import isLink from '../utils/isLink'; -import isPage from '../utils/isPage'; -import isNote from '../utils/isNote'; -import isText from '../utils/isText'; -import isImage from '../utils/isImage'; -import isCanvas from '../utils/isCanvas'; -import save from '../operations/save'; import setLink from '../operations/setLink'; -import restore from '../operations/restore'; import clipNode from '../operations/clipNode'; import transform from '../operations/transform'; import setDestination from '../operations/setDestination'; -const shouldRenderChildren = v => !isText(v) && !isSvg(v); - -const isOverflowHidden = R.pathEq(['style', 'overflow'], 'hidden'); +const isRecursiveNode = node => node.type !== P.Text && node.type !== P.Svg; -const renderChildren = ctx => node => { - save(ctx, node); +const renderChildren = (ctx, node) => { + ctx.save(); if (node.box) { ctx.translate(node.box.left, node.box.top); } const children = node.children || []; - const renderChild = renderNode(ctx); + const renderChild = child => renderNode(ctx, child); children.forEach(renderChild); - restore(ctx, node); + ctx.restore(); +}; - return node; +const renderFns = { + [P.Text]: renderText, + [P.Note]: renderNote, + [P.Image]: renderImage, + [P.Canvas]: renderCanvas, + [P.Svg]: renderSvg, + [P.Link]: setLink, }; -const renderNode = ctx => node => - R.compose( - restore(ctx), - renderDebug(ctx), - setDestination(ctx), - R.when(shouldRenderChildren, renderChildren(ctx)), - R.when(isLink, setLink(ctx)), - R.cond([ - [isText, renderText(ctx)], - [isNote, renderNote(ctx)], - [isImage, renderImage(ctx)], - [isCanvas, renderCanvas(ctx)], - [isSvg, renderSvg(ctx)], - [R.T, R.identity], - ]), - renderBorders(ctx), - renderBackground(ctx), - transform(ctx), - R.when(isOverflowHidden, clipNode(ctx)), - save(ctx), - R.when(isPage, renderPage(ctx)), - )(node); +const renderNode = (ctx, node) => { + const overflowHidden = node.style?.overflow === 'hidden'; + const shouldRenderChildren = isRecursiveNode(node); + + if (node.type === P.Page) renderPage(ctx, node); + + ctx.save(); + + if (overflowHidden) clipNode(ctx, node); + + transform(ctx, node); + renderBackground(ctx, node); + renderBorders(ctx, node); + + const renderFn = renderFns[node.type]; + + if (renderFn) renderFn(ctx, node); + + if (shouldRenderChildren) renderChildren(ctx, node); + + setDestination(ctx, node); + renderDebug(ctx, node); + + ctx.restore(); +}; export default renderNode; diff --git a/packages/render/src/primitives/renderNote.js b/packages/render/src/primitives/renderNote.js index c3d03befe..1dd44993d 100644 --- a/packages/render/src/primitives/renderNote.js +++ b/packages/render/src/primitives/renderNote.js @@ -1,12 +1,8 @@ -import * as R from 'ramda'; - const renderNote = (ctx, node) => { const { top, left } = node.box; const value = node?.children?.[0].value || ''; ctx.note(left, top, 0, 0, value); - - return node; }; -export default R.curryN(2, renderNote); +export default renderNote; diff --git a/packages/render/src/primitives/renderPage.js b/packages/render/src/primitives/renderPage.js index 7e46051ea..657158892 100644 --- a/packages/render/src/primitives/renderPage.js +++ b/packages/render/src/primitives/renderPage.js @@ -1,11 +1,7 @@ -import * as R from 'ramda'; - const renderPage = (ctx, node) => { const { width, height } = node.box; ctx.addPage({ size: [width, height], margin: 0 }); - - return node; }; -export default R.curryN(2, renderPage); +export default renderPage; diff --git a/packages/render/src/primitives/renderPath.js b/packages/render/src/primitives/renderPath.js index af5daf623..b645aa195 100644 --- a/packages/render/src/primitives/renderPath.js +++ b/packages/render/src/primitives/renderPath.js @@ -1,9 +1,7 @@ -import * as R from 'ramda'; +const renderPath = (ctx, node) => { + const d = node.props?.d; -const renderPath = ctx => - R.tap(node => { - const d = R.path(['props', 'd'], node); - if (d) ctx.path(node.props.d); - }); + if (d) ctx.path(node.props.d); +}; export default renderPath; diff --git a/packages/render/src/primitives/renderPolygon.js b/packages/render/src/primitives/renderPolygon.js index 8aada17b3..371f2586f 100644 --- a/packages/render/src/primitives/renderPolygon.js +++ b/packages/render/src/primitives/renderPolygon.js @@ -1,13 +1,8 @@ -import * as R from 'ramda'; - import renderPolyline from './renderPolyline'; -const closePath = ctx => R.tap(() => ctx.closePath()); - -const renderPolygon = ctx => - R.compose( - closePath(ctx), - renderPolyline(ctx), - ); +const renderPolygon = (ctx, node) => { + renderPolyline(ctx, node); + ctx.closePath(); +}; export default renderPolygon; diff --git a/packages/render/src/primitives/renderPolyline.js b/packages/render/src/primitives/renderPolyline.js index 68d4db9a7..959cc74b5 100644 --- a/packages/render/src/primitives/renderPolyline.js +++ b/packages/render/src/primitives/renderPolyline.js @@ -1,21 +1,15 @@ -import * as R from 'ramda'; - import parsePoints from '../svg/parsePoints'; -export const drawPolyline = ctx => points => { +export const drawPolyline = (ctx, points) => { if (points.length > 0) { ctx.moveTo(points[0][0], points[0][1]); points.slice(1).forEach(p => ctx.lineTo(p[0], p[1])); } }; -const renderPolyline = ctx => - R.tap( - R.compose( - drawPolyline(ctx), - parsePoints, - R.pathOr('', ['props', 'points']), - ), - ); +const renderPolyline = (ctx, node) => { + const points = parsePoints(node.props.points || ''); + drawPolyline(ctx, points); +}; export default renderPolyline; diff --git a/packages/render/src/primitives/renderRect.js b/packages/render/src/primitives/renderRect.js index 31ee5ab07..4e3c8cbc6 100644 --- a/packages/render/src/primitives/renderRect.js +++ b/packages/render/src/primitives/renderRect.js @@ -1,18 +1,14 @@ -import * as R from 'ramda'; - const KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0); -const getProp = (d, p, v) => R.pathOr(d, ['props', p], v); - -const renderRect = ctx => node => { - const x = getProp(0, 'x', node); - const y = getProp(0, 'y', node); - const rx = getProp(0, 'rx', node); - const ry = getProp(0, 'ry', node); - const width = getProp(0, 'width', node); - const height = getProp(0, 'height', node); +const renderRect = (ctx, node) => { + const x = node.props?.x || 0; + const y = node.props?.y || 0; + const rx = node.props?.rx || 0; + const ry = node.props?.ry || 0; + const width = node.props?.width || 0; + const height = node.props?.height || 0; - if (!width || !height) return node; + if (!width || !height) return; if (rx && ry) { const krx = rx * KAPPA; @@ -56,8 +52,6 @@ const renderRect = ctx => node => { } ctx.closePath(); - - return node; }; export default renderRect; diff --git a/packages/render/src/primitives/renderSvg.js b/packages/render/src/primitives/renderSvg.js index 3459a0b95..f1a4fc333 100644 --- a/packages/render/src/primitives/renderSvg.js +++ b/packages/render/src/primitives/renderSvg.js @@ -1,4 +1,3 @@ -import * as R from 'ramda'; import * as P from '@react-pdf/primitives'; import renderPath from './renderPath'; @@ -11,175 +10,133 @@ import renderEllipse from './renderEllipse'; import renderPolygon from './renderPolygon'; import renderPolyline from './renderPolyline'; import renderSvgImage from './renderSvgImage'; -import isPath from '../utils/isPath'; -import isText from '../utils/isText'; -import isRect from '../utils/isRect'; -import isLine from '../utils/isLine'; -import isTspan from '../utils/isTspan'; -import isImage from '../utils/isImage'; -import isGroup from '../utils/isGroup'; -import isCircle from '../utils/isCircle'; -import isEllipse from '../utils/isEllipse'; -import isPolygon from '../utils/isPolygon'; -import isPolyline from '../utils/isPolyline'; -import isTextInstance from '../utils/isTextInstance'; -import save from '../operations/save'; -import restore from '../operations/restore'; import clipNode from '../operations/clipNode'; import transform from '../operations/transform'; import getBoundingBox from '../svg/getBoundingBox'; +import isNil from '../../../fns/isNil'; -const warnUnsupportedNode = R.tap(node => { - console.warn(`SVG node of type ${node.type} is not currenty supported`); -}); - -const getProp = (d, p, v) => R.pathOr(d, ['props', p], v); - -const setStrokeWidth = ctx => node => { - const lineWidth = getProp(0, 'strokeWidth', node); +const setStrokeWidth = (ctx, node) => { + const lineWidth = node.props?.strokeWidth || 0; if (lineWidth) ctx.lineWidth(lineWidth); - return node; }; -const setStrokeColor = ctx => node => { - const strokeColor = getProp(null, 'stroke', node); +const setStrokeColor = (ctx, node) => { + const strokeColor = node.props?.stroke || null; if (strokeColor) ctx.strokeColor(strokeColor); - return node; }; -const setOpacity = ctx => node => { - const opacity = getProp(null, 'opacity', node); - if (!R.isNil(opacity)) ctx.opacity(opacity); - return node; +const setOpacity = (ctx, node) => { + const opacity = node.props?.opacity || null; + if (!isNil(opacity)) ctx.opacity(opacity); }; -const setFillOpacity = ctx => node => { - const fillOpacity = getProp(null, 'fillOpacity', node); - if (!R.isNil(fillOpacity)) ctx.fillOpacity(fillOpacity); - return node; +const setFillOpacity = (ctx, node) => { + const fillOpacity = node.props?.fillOpacity || null; + if (!isNil(fillOpacity)) ctx.fillOpacity(fillOpacity); }; -const setStrokeOpacity = ctx => node => { - const strokeOpacity = getProp(null, 'strokeOpacity', node); - if (!R.isNil(strokeOpacity)) ctx.strokeOpacity(strokeOpacity); - return node; +const setStrokeOpacity = (ctx, node) => { + const strokeOpacity = node.props?.strokeOpacity || null; + if (!isNil(strokeOpacity)) ctx.strokeOpacity(strokeOpacity); }; -const setLineJoin = ctx => node => { - const lineJoin = getProp(null, 'strokeLinejoin', node); +const setLineJoin = (ctx, node) => { + const lineJoin = node.props?.strokeLinejoin || null; if (lineJoin) ctx.lineJoin(lineJoin); - return node; }; -const setLineCap = ctx => node => { - const lineCap = getProp(null, 'strokeLinecap', node); +const setLineCap = (ctx, node) => { + const lineCap = node.props?.strokeLinecap || null; if (lineCap) ctx.lineCap(lineCap); - return node; }; -const setLineDash = ctx => node => { - const value = getProp(null, 'strokeDasharray', node); - - if (value) ctx.dash(R.split(',', value)); +const setLineDash = (ctx, node) => { + const value = node.props?.strokeDasharray || null; - return node; + if (value) ctx.dash(value.split(',')); }; -const hasLinearGradientFill = R.pathEq( - ['props', 'fill', 'type'], - P.LinearGradient, -); +const hasLinearGradientFill = node => + node.props?.fill?.type === P.LinearGradient; -const hasRadialGradientFill = R.pathEq( - ['props', 'fill', 'type'], - P.RadialGradient, -); +const hasRadialGradientFill = node => + node.props?.fill?.type === P.RadialGradient; // Math simplified from https://github.com/devongovett/svgkit/blob/master/src/elements/SVGGradient.js#L104 -const setLinearGradientFill = ctx => - R.tap(node => { - const bbox = getBoundingBox(node); - const gradient = getProp(null, 'fill', node); - - const x1 = R.pathOr(0, ['props', 'x1'], gradient); - const y1 = R.pathOr(0, ['props', 'y1'], gradient); - const x2 = R.pathOr(1, ['props', 'x2'], gradient); - const y2 = R.pathOr(0, ['props', 'y2'], gradient); - - const m0 = bbox[2] - bbox[0]; - const m3 = bbox[3] - bbox[1]; - const m4 = bbox[0]; - const m5 = bbox[1]; - - const gx1 = m0 * x1 + m4; - const gy1 = m3 * y1 + m5; - const gx2 = m0 * x2 + m4; - const gy2 = m3 * y2 + m5; - - const grad = ctx.linearGradient(gx1, gy1, gx2, gy2); - - gradient.children.forEach(stop => { - grad.stop( - stop.props.offset, - stop.props.stopColor, - stop.props.stopOpacity, - ); - }); - - ctx.fill(grad); +const setLinearGradientFill = (ctx, node) => { + const bbox = getBoundingBox(node); + const gradient = node.props?.fill || null; + + const x1 = gradient.props.x1 || 0; + const y1 = gradient.props.y1 || 0; + const x2 = gradient.props.x2 || 1; + const y2 = gradient.props.y2 || 0; + + const m0 = bbox[2] - bbox[0]; + const m3 = bbox[3] - bbox[1]; + const m4 = bbox[0]; + const m5 = bbox[1]; + + const gx1 = m0 * x1 + m4; + const gy1 = m3 * y1 + m5; + const gx2 = m0 * x2 + m4; + const gy2 = m3 * y2 + m5; + + const grad = ctx.linearGradient(gx1, gy1, gx2, gy2); + + gradient.children.forEach(stop => { + grad.stop(stop.props.offset, stop.props.stopColor, stop.props.stopOpacity); }); + ctx.fill(grad); +}; + // Math simplified from https://github.com/devongovett/svgkit/blob/master/src/elements/SVGGradient.js#L155 -const setRadialGradientFill = ctx => - R.tap(node => { - const bbox = getBoundingBox(node); - const gradient = getProp(null, 'fill', node); - - const cx = R.pathOr(0.5, ['props', 'cx'], gradient); - const cy = R.pathOr(0.5, ['props', 'cy'], gradient); - const fx = R.pathOr(cx, ['props', 'fx'], gradient); - const fy = R.pathOr(cy, ['props', 'fy'], gradient); - const r = R.pathOr(0.5, ['props', 'r'], gradient); - - const m0 = bbox[2] - bbox[0]; - const m3 = bbox[3] - bbox[1]; - const m4 = bbox[0]; - const m5 = bbox[1]; - - const gr = r * m0; - const gcx = m0 * cx + m4; - const gcy = m3 * cy + m5; - const gfx = m0 * fx + m4; - const gfy = m3 * fy + m5; - - const grad = ctx.radialGradient(gfx, gfy, 0, gcx, gcy, gr); - - gradient.children.forEach(stop => { - grad.stop( - stop.props.offset, - stop.props.stopColor, - stop.props.stopOpacity, - ); - }); - - ctx.fill(grad); +const setRadialGradientFill = (ctx, node) => { + const bbox = getBoundingBox(node); + const gradient = node.props?.fill || null; + + const cx = gradient.props.cx || 0.5; + const cy = gradient.props.cy || 0.5; + const fx = gradient.props.fx || cx; + const fy = gradient.props.fy || cy; + const r = gradient.props.r || 0.5; + + const m0 = bbox[2] - bbox[0]; + const m3 = bbox[3] - bbox[1]; + const m4 = bbox[0]; + const m5 = bbox[1]; + + const gr = r * m0; + const gcx = m0 * cx + m4; + const gcy = m3 * cy + m5; + const gfx = m0 * fx + m4; + const gfy = m3 * fy + m5; + + const grad = ctx.radialGradient(gfx, gfy, 0, gcx, gcy, gr); + + gradient.children.forEach(stop => { + grad.stop(stop.props.offset, stop.props.stopColor, stop.props.stopOpacity); }); -const setFillColor = ctx => - R.tap(node => { - const fillColor = getProp(null, 'fill', node); - if (fillColor) ctx.fillColor(fillColor); - }); + ctx.fill(grad); +}; -const setFill = ctx => - R.cond([ - [hasLinearGradientFill, setLinearGradientFill(ctx)], - [hasRadialGradientFill, setRadialGradientFill(ctx)], - [R.T, setFillColor(ctx)], - ]); +const setFillColor = (ctx, node) => { + const fillColor = node.props?.fill || null; + + if (fillColor) ctx.fillColor(fillColor); +}; -const draw = ctx => node => { - const props = R.propOr({}, 'props', node); +const setFill = (ctx, node) => { + if (hasLinearGradientFill(node)) return setLinearGradientFill(ctx, node); + if (hasRadialGradientFill(node)) return setRadialGradientFill(ctx, node); + + return setFillColor(ctx, node); +}; + +const draw = (ctx, node) => { + const props = node.props || {}; if (props.fill && props.stroke) { ctx.fillAndStroke(props.fillRule); @@ -193,79 +150,80 @@ const draw = ctx => node => { ctx.fill(null); ctx.restore(); } +}; + +const noop = () => {}; + +const renderFns = { + [P.Tspan]: noop, + [P.TextInstance]: noop, + [P.Path]: renderPath, + [P.Rect]: renderRect, + [P.Line]: renderLine, + [P.G]: renderGroup, + [P.Text]: renderSvgText, + [P.Circle]: renderCircle, + [P.Image]: renderSvgImage, + [P.Ellipse]: renderEllipse, + [P.Polygon]: renderPolygon, + [P.Polyline]: renderPolyline, +}; + +const renderNode = (ctx, node) => { + const renderFn = renderFns[node.type]; + + if (renderFns) { + renderFn(ctx, node); + } else { + console.warn(`SVG node of type ${node.type} is not currenty supported`); + } +}; - return node; +const drawNode = (ctx, node) => { + setLineCap(ctx, node); + setLineDash(ctx, node); + setLineJoin(ctx, node); + setStrokeWidth(ctx, node); + setStrokeColor(ctx, node); + setFill(ctx, node); + setStrokeOpacity(ctx, node); + setFillOpacity(ctx, node); + setOpacity(ctx, node); + transform(ctx, node); + renderNode(ctx, node); + draw(ctx, node); }; -const renderNode = ctx => - R.cond([ - [isTspan, R.identity], - [isTextInstance, R.identity], - [isPath, renderPath(ctx)], - [isRect, renderRect(ctx)], - [isLine, renderLine(ctx)], - [isGroup, renderGroup(ctx)], - [isText, renderSvgText(ctx)], - [isCircle, renderCircle(ctx)], - [isImage, renderSvgImage(ctx)], - [isEllipse, renderEllipse(ctx)], - [isPolygon, renderPolygon(ctx)], - [isPolyline, renderPolyline(ctx)], - [R.T, warnUnsupportedNode], - ]); - -const drawNode = ctx => - R.compose( - draw(ctx), - renderNode(ctx), - transform(ctx), - setOpacity(ctx), - setFillOpacity(ctx), - setStrokeOpacity(ctx), - setFill(ctx), - setStrokeColor(ctx), - setStrokeWidth(ctx), - setLineJoin(ctx), - setLineDash(ctx), - setLineCap(ctx), - ); - -const clipPath = ctx => node => { - const value = R.path(['props', 'clipPath'], node); +const clipPath = (ctx, node) => { + const value = node.props?.clipPath; if (value) { - R.compose( - () => ctx.clip(), - R.forEach(renderNode(ctx)), - R.propOr([], 'children'), - )(value); + const children = value.children || []; + children.forEach(child => renderNode(ctx, child)); + ctx.clip(); } +}; + +const drawChildren = (ctx, node) => { + const children = node.children || []; - return node; + children.forEach(child => { + ctx.save(); + + clipPath(ctx, child); + drawNode(ctx, child); + drawChildren(ctx, child); + + ctx.restore(); + }); }; -const drawChildren = ctx => node => - R.compose( - R.map( - R.compose( - restore(ctx), - drawChildren(ctx), - drawNode(ctx), - clipPath(ctx), - save(ctx), - ), - ), - R.propOr([], 'children'), - )(node); - -const defaultsZero = R.pathOr(0); - -const resolveAspectRatio = ctx => node => { +const resolveAspectRatio = (ctx, node) => { const { width, height } = node.box; const { viewBox, preserveAspectRatio = {} } = node.props; const { meetOrSlice = 'meet', align = 'xMidYMid' } = preserveAspectRatio; - if (viewBox == null || width == null || height == null) return node; + if (viewBox == null || width == null || height == null) return; const x = viewBox?.minX || 0; const y = viewBox?.minY || 0; @@ -280,7 +238,7 @@ const resolveAspectRatio = ctx => node => { if (align === 'none') { ctx.scale(scaleX, scaleY); ctx.translate(-x, -y); - return node; + return; } if ( @@ -337,32 +295,26 @@ const resolveAspectRatio = ctx => node => { ); } } - - return node; }; -const moveToOrigin = ctx => node => { +const moveToOrigin = (ctx, node) => { const { top, left } = node.box; - const paddingLeft = defaultsZero('paddingLeft', node.box); - const paddingTop = defaultsZero('paddingTop', node.box); + const paddingLeft = node.box.paddingLeft || 0; + const paddingTop = node.box.paddingTop || 0; ctx.translate(left + paddingLeft, top + paddingTop); - - return node; }; const renderSvg = (ctx, node) => { - R.compose( - restore(ctx), - drawChildren(ctx), - resolveAspectRatio(ctx), - moveToOrigin(ctx), - clipNode(ctx), - save(ctx), - )(node); - - return node; + ctx.save(); + + clipNode(ctx, node); + moveToOrigin(ctx, node); + resolveAspectRatio(ctx, node); + drawChildren(ctx, node); + + ctx.restore(); }; -export default R.curryN(2, renderSvg); +export default renderSvg; diff --git a/packages/render/src/primitives/renderSvgImage.js b/packages/render/src/primitives/renderSvgImage.js index 861dc9845..8181d5f47 100644 --- a/packages/render/src/primitives/renderSvgImage.js +++ b/packages/render/src/primitives/renderSvgImage.js @@ -1,40 +1,28 @@ -import * as R from 'ramda'; - -import save from '../operations/save'; -import restore from '../operations/restore'; +const renderImage = (ctx, node) => { + if (!node.image.data) return; -const drawImage = ctx => node => { const { x, y } = node.props; const { width, height, opacity } = node.style; const paddingTop = node.box.paddingLeft || 0; const paddingLeft = node.box.paddingLeft || 0; - if (node.image.data) { - if (width !== 0 && height !== 0) { - ctx - .fillOpacity(opacity || 1) - .image(node.image.data, x + paddingLeft, y + paddingTop, { - width, - height, - }); - } else { - console.warn( - `Image with src '${node.props.href}' skipped due to invalid dimensions`, - ); - } + if (width === 0 || height === 0) { + console.warn( + `Image with src '${node.props.href}' skipped due to invalid dimensions`, + ); + return; } - return node; -}; + ctx.save(); -const renderImage = (ctx, node) => { - R.compose( - restore(ctx), - drawImage(ctx), - save(ctx), - )(node); + ctx + .fillOpacity(opacity || 1) + .image(node.image.data, x + paddingLeft, y + paddingTop, { + width, + height, + }); - return node; + ctx.restore(); }; -export default R.curryN(2, renderImage); +export default renderImage; diff --git a/packages/render/src/primitives/renderSvgText.js b/packages/render/src/primitives/renderSvgText.js index db70e1f0c..94f766e0f 100644 --- a/packages/render/src/primitives/renderSvgText.js +++ b/packages/render/src/primitives/renderSvgText.js @@ -1,4 +1,3 @@ -import * as R from 'ramda'; import runWidth from '@react-pdf/textkit/lib/run/advanceWidth'; import lineWidth from '@react-pdf/textkit/lib/attributedString/advanceWidth'; @@ -45,10 +44,10 @@ const renderRun = (ctx, run) => { const renderSpan = (ctx, line, textAnchor, dominantBaseline) => { ctx.save(); - const x = R.pathOr(0, ['box', 'x'], line); - const y = R.pathOr(0, ['box', 'y'], line); - const font = R.pathOr(1, ['runs', 0, 'attributes', 'font'], line); - const scale = R.pathOr(1, ['runs', 0, 'attributes', 'scale'], line); + const x = line.box?.x || 0; + const y = line.box?.y || 0; + const font = line.runs[0]?.attributes.font; + const scale = line.runs[0]?.attributes?.scale || 1; const width = lineWidth(line); const ascent = font.ascent * scale; @@ -100,7 +99,7 @@ const renderSpan = (ctx, line, textAnchor, dominantBaseline) => { ctx.restore(); }; -const renderSvgText = ctx => node => { +const renderSvgText = (ctx, node) => { node.children.forEach(span => renderSpan( ctx, @@ -109,8 +108,6 @@ const renderSvgText = ctx => node => { span.props.dominantBaseline, ), ); - - return node; }; export default renderSvgText; diff --git a/packages/render/src/primitives/renderText.js b/packages/render/src/primitives/renderText.js index 063459fc9..190197e4f 100644 --- a/packages/render/src/primitives/renderText.js +++ b/packages/render/src/primitives/renderText.js @@ -1,6 +1,5 @@ /* eslint-disable no-param-reassign */ -import * as R from 'ramda'; import runHeight from '@react-pdf/textkit/lib/run/height'; import runDescent from '@react-pdf/textkit/lib/run/descent'; import advanceWidth from '@react-pdf/textkit/lib/run/advanceWidth'; @@ -8,6 +7,7 @@ import ascent from '@react-pdf/textkit/lib/attributedString/ascent'; import renderGlyphs from './renderGlyphs'; import parseColor from '../utils/parseColor'; +import isNil from '../../../fns/isNil'; const DEST_REGEXP = /^#.+/; @@ -53,7 +53,9 @@ const renderAttachments = (ctx, run) => { const renderRun = (ctx, run, options) => { const { font, fontSize, link } = run.attributes; const color = parseColor(run.attributes.color); - const opacity = R.defaultTo(color.opacity, run.attributes.opacity); + const opacity = isNil(run.attributes.opacity) + ? color.opacity + : run.attributes.opacity; const height = runHeight(run); const descent = runDescent(run); @@ -222,8 +224,8 @@ const renderBlock = (ctx, block, options) => { const renderText = (ctx, node) => { const { top, left } = node.box; const blocks = [node.lines]; - const paddingTop = R.pathOr(0, ['box', 'paddingTop'], node); - const paddingLeft = R.pathOr(0, ['box', 'paddingLeft'], node); + const paddingTop = node.box?.paddingTop || 0; + const paddingLeft = node.box?.paddingLeft || 0; const initialY = node.lines[0] ? node.lines[0].box.y : 0; const offsetX = node.alignOffset || 0; @@ -235,8 +237,6 @@ const renderText = (ctx, node) => { }); ctx.restore(); - - return node; }; -export default R.curryN(2, renderText); +export default renderText; diff --git a/packages/render/src/svg/getBoundingBox.js b/packages/render/src/svg/getBoundingBox.js index 34fefc7cf..2aeb16f28 100644 --- a/packages/render/src/svg/getBoundingBox.js +++ b/packages/render/src/svg/getBoundingBox.js @@ -1,25 +1,13 @@ -import * as R from 'ramda'; +import * as P from '@react-pdf/primitives'; import absPath from 'abs-svg-path'; import parsePath from 'parse-svg-path'; import normalizePath from 'normalize-svg-path'; -import isRect from '../utils/isRect'; -import isLine from '../utils/isLine'; -import isPath from '../utils/isPath'; -import isCircle from '../utils/isCircle'; -import isPolygon from '../utils/isPolygon'; -import isEllipse from '../utils/isEllipse'; -import isPolyline from '../utils/isPolyline'; import parsePoints from './parsePoints'; // From https://github.com/dy/svg-path-bounds/blob/master/index.js const getPathBoundingBox = node => { - const path = R.compose( - normalizePath, - absPath, - parsePath, - R.pathOr('', ['props', 'd']), - )(node); + const path = normalizePath(absPath(parsePath(node.props?.d || ''))); if (!path.length) return [0, 0, 0, 0]; @@ -40,64 +28,70 @@ const getPathBoundingBox = node => { }; const getCircleBoundingBox = node => { - const r = R.pathOr(0, ['props', 'r'], node); - const cx = R.pathOr(0, ['props', 'cx'], node); - const cy = R.pathOr(0, ['props', 'cy'], node); + const r = node.props?.r || 0; + const cx = node.props?.cx || 0; + const cy = node.props?.cy || 0; return [cx - r, cy - r, cx + r, cy + r]; }; const getEllipseBoundingBox = node => { - const cx = R.pathOr(0, ['props', 'cx'], node); - const cy = R.pathOr(0, ['props', 'cy'], node); - const rx = R.pathOr(0, ['props', 'rx'], node); - const ry = R.pathOr(0, ['props', 'ry'], node); + const cx = node.props?.cx || 0; + const cy = node.props?.cy || 0; + const rx = node.props?.rx || 0; + const ry = node.props?.ry || 0; return [cx - rx, cy - ry, cx + rx, cy + ry]; }; const getLineBoundingBox = node => { - const x1 = R.pathOr(0, ['props', 'x1'], node); - const y1 = R.pathOr(0, ['props', 'y1'], node); - const x2 = R.pathOr(0, ['props', 'x2'], node); - const y2 = R.pathOr(0, ['props', 'y2'], node); - - return [R.min(x1, x2), R.min(y1, y2), R.max(x1, x2), R.max(y1, y2)]; + const x1 = node.props?.x1 || 0; + const y1 = node.props?.y1 || 0; + const x2 = node.props?.x2 || 0; + const y2 = node.props?.y2 || 0; + + return [ + Math.min(x1, x2), + Math.min(y1, y2), + Math.max(x1, x2), + Math.max(y1, y2), + ]; }; const getRectBoundingBox = node => { - const x = R.pathOr(0, ['props', 'x'], node); - const y = R.pathOr(0, ['props', 'y'], node); - const width = R.pathOr(0, ['props', 'width'], node); - const height = R.pathOr(0, ['props', 'height'], node); + const x = node.props?.x || 0; + const y = node.props?.y || 0; + const width = node.props?.width || 0; + const height = node.props?.height || 0; return [x, y, x + width, y + height]; }; -const max = R.reduce(R.max, -Infinity); -const min = R.reduce(R.min, Infinity); +const max = values => Math.max(-Infinity, ...values); +const min = values => Math.min(Infinity, ...values); const getPolylineBoundingBox = node => { - const points = R.compose( - parsePoints, - R.pathOr([], ['props', 'points']), - )(node); + const points = parsePoints(node.props?.points || []); - const xValues = R.pluck(0, points); - const yValues = R.pluck(1, points); + const xValues = points.map(p => p[0]); + const yValues = points.map(p => p[1]); return [min(xValues), min(yValues), max(xValues), max(yValues)]; }; -const getBoundingBox = R.cond([ - [isRect, getRectBoundingBox], - [isLine, getLineBoundingBox], - [isPath, getPathBoundingBox], - [isCircle, getCircleBoundingBox], - [isEllipse, getEllipseBoundingBox], - [isPolygon, getPolylineBoundingBox], - [isPolyline, getPolylineBoundingBox], - [R.T, R.always([0, 0, 0, 0])], -]); +const boundingBoxFns = { + [P.Rect]: getRectBoundingBox, + [P.Line]: getLineBoundingBox, + [P.Path]: getPathBoundingBox, + [P.Circle]: getCircleBoundingBox, + [P.Ellipse]: getEllipseBoundingBox, + [P.Polygon]: getPolylineBoundingBox, + [P.Polyline]: getPolylineBoundingBox, +}; + +const getBoundingBox = node => { + const boundingBoxFn = boundingBoxFns[node.type]; + return boundingBoxFn ? boundingBoxFn(node) : [0, 0, 0, 0]; +}; export default getBoundingBox; diff --git a/packages/render/src/svg/parsePoints.js b/packages/render/src/svg/parsePoints.js index 9fa9c4317..369480115 100644 --- a/packages/render/src/svg/parsePoints.js +++ b/packages/render/src/svg/parsePoints.js @@ -1,8 +1,12 @@ -import * as R from 'ramda'; +const pairs = values => { + const result = []; -const isOdd = x => x % 2 !== 0; + for (let i = 0; i < values.length; i += 2) { + result.push([values[i], values[i + 1]]); + } -const lengthIsOdd = R.o(isOdd, R.prop('length')); + return result; +}; /** * Parse svg-like points into number arrays @@ -10,15 +14,20 @@ const lengthIsOdd = R.o(isOdd, R.prop('length')); * @param {String} points string ex. "20,30 50,60" * @return {Array} points array ex. [[20, 30], [50, 60]] */ -const parsePoints = R.compose( - R.splitEvery(2), - R.map(parseFloat), - R.when(lengthIsOdd, R.slice(0, -1)), - R.split(/\s+/), - R.replace(/(\d)-(\d)/g, '$1 -$2'), - R.replace(/,/g, ' '), - R.trim, - R.defaultTo(''), -); +const parsePoints = points => { + let values = (points || '') + .trim() + .replace(/,/g, ' ') + .replace(/(\d)-(\d)/g, '$1 -$2') + .split(/\s+/); + + if (values.length % 2 !== 0) { + values = values.slice(0, -1); + } + + values = values.map(parseFloat); + + return pairs(values); +}; export default parsePoints; diff --git a/packages/render/src/utils/isCanvas.js b/packages/render/src/utils/isCanvas.js deleted file mode 100644 index d8c7feda0..000000000 --- a/packages/render/src/utils/isCanvas.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isCanvas = R.propEq('type', P.Canvas); - -export default isCanvas; diff --git a/packages/render/src/utils/isCircle.js b/packages/render/src/utils/isCircle.js deleted file mode 100644 index 686296193..000000000 --- a/packages/render/src/utils/isCircle.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isCircle = R.propEq('type', P.Circle); - -export default isCircle; diff --git a/packages/render/src/utils/isEllipse.js b/packages/render/src/utils/isEllipse.js deleted file mode 100644 index eb96b0987..000000000 --- a/packages/render/src/utils/isEllipse.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isEllipse = R.propEq('type', P.Ellipse); - -export default isEllipse; diff --git a/packages/render/src/utils/isGroup.js b/packages/render/src/utils/isGroup.js deleted file mode 100644 index 6d3dda497..000000000 --- a/packages/render/src/utils/isGroup.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isGroup = R.propEq('type', P.G); - -export default isGroup; diff --git a/packages/render/src/utils/isImage.js b/packages/render/src/utils/isImage.js deleted file mode 100644 index 738a67a8e..000000000 --- a/packages/render/src/utils/isImage.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isImage = R.propEq('type', P.Image); - -export default isImage; diff --git a/packages/render/src/utils/isLine.js b/packages/render/src/utils/isLine.js deleted file mode 100644 index 3ac741bd4..000000000 --- a/packages/render/src/utils/isLine.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isLine = R.propEq('type', P.Line); - -export default isLine; diff --git a/packages/render/src/utils/isLink.js b/packages/render/src/utils/isLink.js deleted file mode 100644 index 0b0e36fe2..000000000 --- a/packages/render/src/utils/isLink.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isLink = R.propEq('type', P.Link); - -export default isLink; diff --git a/packages/render/src/utils/isNote.js b/packages/render/src/utils/isNote.js deleted file mode 100644 index f7ef43eb3..000000000 --- a/packages/render/src/utils/isNote.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isNote = R.propEq('type', P.Note); - -export default isNote; diff --git a/packages/render/src/utils/isPage.js b/packages/render/src/utils/isPage.js deleted file mode 100644 index 2eaf4c6f6..000000000 --- a/packages/render/src/utils/isPage.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isPage = R.propEq('type', P.Page); - -export default isPage; diff --git a/packages/render/src/utils/isPath.js b/packages/render/src/utils/isPath.js deleted file mode 100644 index b2292b217..000000000 --- a/packages/render/src/utils/isPath.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isPath = R.propEq('type', P.Path); - -export default isPath; diff --git a/packages/render/src/utils/isPolygon.js b/packages/render/src/utils/isPolygon.js deleted file mode 100644 index 684d01f50..000000000 --- a/packages/render/src/utils/isPolygon.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isPolygon = R.propEq('type', P.Polygon); - -export default isPolygon; diff --git a/packages/render/src/utils/isPolyline.js b/packages/render/src/utils/isPolyline.js deleted file mode 100644 index aaa194807..000000000 --- a/packages/render/src/utils/isPolyline.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isPolyline = R.propEq('type', P.Polyline); - -export default isPolyline; diff --git a/packages/render/src/utils/isRadialGradient.js b/packages/render/src/utils/isRadialGradient.js deleted file mode 100644 index c4ea810ee..000000000 --- a/packages/render/src/utils/isRadialGradient.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isRadialGradient = R.propEq('type', P.RadialGradient); - -export default isRadialGradient; diff --git a/packages/render/src/utils/isRect.js b/packages/render/src/utils/isRect.js deleted file mode 100644 index bf86359f7..000000000 --- a/packages/render/src/utils/isRect.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isRect = R.propEq('type', P.Rect); - -export default isRect; diff --git a/packages/render/src/utils/isSvg.js b/packages/render/src/utils/isSvg.js deleted file mode 100644 index 302da533f..000000000 --- a/packages/render/src/utils/isSvg.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isSvg = R.propEq('type', P.Svg); - -export default isSvg; diff --git a/packages/render/src/utils/isText.js b/packages/render/src/utils/isText.js deleted file mode 100644 index 29973ac3e..000000000 --- a/packages/render/src/utils/isText.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isText = R.propEq('type', P.Text); - -export default isText; diff --git a/packages/render/src/utils/isTextInstance.js b/packages/render/src/utils/isTextInstance.js deleted file mode 100644 index a126898c0..000000000 --- a/packages/render/src/utils/isTextInstance.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isTextInstance = R.propEq('type', P.TextInstance); - -export default isTextInstance; diff --git a/packages/render/src/utils/isTspan.js b/packages/render/src/utils/isTspan.js deleted file mode 100644 index cf6fb194f..000000000 --- a/packages/render/src/utils/isTspan.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as R from 'ramda'; -import * as P from '@react-pdf/primitives'; - -const isTspan = R.propEq('type', P.Tspan); - -export default isTspan; diff --git a/packages/render/tests/operations/addMetadata.test.js b/packages/render/tests/operations/addMetadata.test.js index d64077606..da41e8f25 100644 --- a/packages/render/tests/operations/addMetadata.test.js +++ b/packages/render/tests/operations/addMetadata.test.js @@ -111,11 +111,4 @@ describe('operations addMetadata', () => { expect(ctx.info.Producer).toBe('test'); }); - - test('should return passed node', () => { - const ctx = createCTX(); - const doc = { type: P.Document }; - - expect(addMetadata(ctx, doc)).toBe(doc); - }); }); diff --git a/packages/render/tests/operations/restore.test.js b/packages/render/tests/operations/restore.test.js deleted file mode 100644 index fdb2e7234..000000000 --- a/packages/render/tests/operations/restore.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as P from '@react-pdf/primitives'; - -import createCTX from '../ctx'; -import restore from '../../src/operations/restore'; - -describe('operations restore', () => { - test('should call restore method to passed context', () => { - const ctx = createCTX(); - const doc = { type: P.Document }; - - restore(ctx, doc); - - expect(ctx.restore.mock.calls).toHaveLength(1); - }); - - test('should return passed node', () => { - const ctx = createCTX(); - const doc = { type: P.Document }; - - expect(restore(ctx, doc)).toBe(doc); - }); -}); diff --git a/packages/render/tests/operations/save.test.js b/packages/render/tests/operations/save.test.js deleted file mode 100644 index ff1d340fb..000000000 --- a/packages/render/tests/operations/save.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as P from '@react-pdf/primitives'; - -import createCTX from '../ctx'; -import save from '../../src/operations/save'; - -describe('operations save', () => { - test('should call save method to passed context', () => { - const ctx = createCTX(); - const doc = { type: P.Document }; - - save(ctx, doc); - - expect(ctx.save.mock.calls).toHaveLength(1); - }); - - test('should return passed node', () => { - const ctx = createCTX(); - const doc = { type: P.Document }; - - expect(save(ctx, doc)).toBe(doc); - }); -}); diff --git a/packages/render/tests/operations/setDestination.test.js b/packages/render/tests/operations/setDestination.test.js index 7fc030ec9..8196d6fdb 100644 --- a/packages/render/tests/operations/setDestination.test.js +++ b/packages/render/tests/operations/setDestination.test.js @@ -25,11 +25,4 @@ describe('operations setDestination', () => { expect(ctx.addNamedDestination.mock.calls).toHaveLength(0); }); - - test('should return passed node', () => { - const ctx = createCTX(); - const doc = { type: P.View }; - - expect(setDestination(ctx, doc)).toBe(doc); - }); }); diff --git a/packages/render/tests/utils/isCanvas.test.js b/packages/render/tests/utils/isCanvas.test.js deleted file mode 100644 index 24fb978d8..000000000 --- a/packages/render/tests/utils/isCanvas.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isCanvas from '../../src/utils/isCanvas'; - -const ASSERTED_TYPE = P.Canvas; -const PRIMITIVES = Object.keys(P); - -describe('is canvas util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isCanvas({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isCircle.test.js b/packages/render/tests/utils/isCircle.test.js deleted file mode 100644 index 110ba65fb..000000000 --- a/packages/render/tests/utils/isCircle.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isCircle from '../../src/utils/isCircle'; - -const ASSERTED_TYPE = P.Circle; -const PRIMITIVES = Object.keys(P); - -describe('is circle util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isCircle({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isEllipse.test.js b/packages/render/tests/utils/isEllipse.test.js deleted file mode 100644 index 00993c394..000000000 --- a/packages/render/tests/utils/isEllipse.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isEllipse from '../../src/utils/isEllipse'; - -const ASSERTED_TYPE = P.Ellipse; -const PRIMITIVES = Object.keys(P); - -describe('is ellipse util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isEllipse({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isGroup.test.js b/packages/render/tests/utils/isGroup.test.js deleted file mode 100644 index c51d8d66a..000000000 --- a/packages/render/tests/utils/isGroup.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isGroup from '../../src/utils/isGroup'; - -const ASSERTED_TYPE = P.G; -const PRIMITIVES = Object.keys(P); - -describe('is group util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isGroup({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isImage.test.js b/packages/render/tests/utils/isImage.test.js deleted file mode 100644 index 3a519f01f..000000000 --- a/packages/render/tests/utils/isImage.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isImage from '../../src/utils/isImage'; - -const ASSERTED_TYPE = P.Image; -const PRIMITIVES = Object.keys(P); - -describe('is image util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isImage({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isLine.test.js b/packages/render/tests/utils/isLine.test.js deleted file mode 100644 index d9368c481..000000000 --- a/packages/render/tests/utils/isLine.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isLine from '../../src/utils/isLine'; - -const ASSERTED_TYPE = P.Line; -const PRIMITIVES = Object.keys(P); - -describe('is line util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isLine({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isLink.test.js b/packages/render/tests/utils/isLink.test.js deleted file mode 100644 index 8dbcdaa60..000000000 --- a/packages/render/tests/utils/isLink.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isLink from '../../src/utils/isLink'; - -const ASSERTED_TYPE = P.Link; -const PRIMITIVES = Object.keys(P); - -describe('is link util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isLink({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isNote.test.js b/packages/render/tests/utils/isNote.test.js deleted file mode 100644 index b985c73ef..000000000 --- a/packages/render/tests/utils/isNote.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isNote from '../../src/utils/isNote'; - -const ASSERTED_TYPE = P.Note; -const PRIMITIVES = Object.keys(P); - -describe('is note util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isNote({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isPage.test.js b/packages/render/tests/utils/isPage.test.js deleted file mode 100644 index ce6e792a2..000000000 --- a/packages/render/tests/utils/isPage.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isPage from '../../src/utils/isPage'; - -const ASSERTED_TYPE = P.Page; -const PRIMITIVES = Object.keys(P); - -describe('is page util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isPage({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isPath.test.js b/packages/render/tests/utils/isPath.test.js deleted file mode 100644 index d4ee5477b..000000000 --- a/packages/render/tests/utils/isPath.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isPath from '../../src/utils/isPath'; - -const ASSERTED_TYPE = P.Path; -const PRIMITIVES = Object.keys(P); - -describe('is path util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isPath({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isPolygon.test.js b/packages/render/tests/utils/isPolygon.test.js deleted file mode 100644 index 5e288f091..000000000 --- a/packages/render/tests/utils/isPolygon.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isPolygon from '../../src/utils/isPolygon'; - -const ASSERTED_TYPE = P.Polygon; -const PRIMITIVES = Object.keys(P); - -describe('is polygon util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isPolygon({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isPolyline.test.js b/packages/render/tests/utils/isPolyline.test.js deleted file mode 100644 index 5a402ffd8..000000000 --- a/packages/render/tests/utils/isPolyline.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isPolyline from '../../src/utils/isPolyline'; - -const ASSERTED_TYPE = P.Polyline; -const PRIMITIVES = Object.keys(P); - -describe('is polyline util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isPolyline({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isReadialGradient.test.js b/packages/render/tests/utils/isReadialGradient.test.js deleted file mode 100644 index ff5afa9f4..000000000 --- a/packages/render/tests/utils/isReadialGradient.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isRadialGradient from '../../src/utils/isRadialGradient'; - -const ASSERTED_TYPE = P.RadialGradient; -const PRIMITIVES = Object.keys(P); - -describe('is radial gradient util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isRadialGradient({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isRect.test.js b/packages/render/tests/utils/isRect.test.js deleted file mode 100644 index 317999483..000000000 --- a/packages/render/tests/utils/isRect.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isRect from '../../src/utils/isRect'; - -const ASSERTED_TYPE = P.Rect; -const PRIMITIVES = Object.keys(P); - -describe('is rect util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isRect({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isSvg.test.js b/packages/render/tests/utils/isSvg.test.js deleted file mode 100644 index c6c00e230..000000000 --- a/packages/render/tests/utils/isSvg.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isSvg from '../../src/utils/isSvg'; - -const ASSERTED_TYPE = P.Svg; -const PRIMITIVES = Object.keys(P); - -describe('is svg util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isSvg({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isText.test.js b/packages/render/tests/utils/isText.test.js deleted file mode 100644 index 038f32e52..000000000 --- a/packages/render/tests/utils/isText.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isText from '../../src/utils/isText'; - -const ASSERTED_TYPE = P.Text; -const PRIMITIVES = Object.keys(P); - -describe('is text util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isText({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isTextInstance.test.js b/packages/render/tests/utils/isTextInstance.test.js deleted file mode 100644 index 5c8af8eb0..000000000 --- a/packages/render/tests/utils/isTextInstance.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isTextInstance from '../../src/utils/isTextInstance'; - -const ASSERTED_TYPE = P.TextInstance; -const PRIMITIVES = Object.keys(P); - -describe('is text instance util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isTextInstance({ type })).toBe(isAssertedType); - }); - }); -}); diff --git a/packages/render/tests/utils/isTspan.test.js b/packages/render/tests/utils/isTspan.test.js deleted file mode 100644 index a8ec9cd21..000000000 --- a/packages/render/tests/utils/isTspan.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as P from '@react-pdf/primitives'; -import isTspan from '../../src/utils/isTspan'; - -const ASSERTED_TYPE = P.Tspan; -const PRIMITIVES = Object.keys(P); - -describe('is tspan instance util', () => { - PRIMITIVES.forEach(type => { - const isAssertedType = type === ASSERTED_TYPE; - const result = isAssertedType ? 'true' : 'false'; - - test(`should return ${result} for ${type} node`, () => { - expect(isTspan({ type })).toBe(isAssertedType); - }); - }); -});