diff --git a/frontend/playwright/data/render-wasm/get-file-empty-lines.json b/frontend/playwright/data/render-wasm/get-file-empty-lines.json new file mode 100644 index 0000000000..94eeaa8fbb --- /dev/null +++ b/frontend/playwright/data/render-wasm/get-file-empty-lines.json @@ -0,0 +1,134 @@ +{ + "~:features": { + "~#set": [ + "fdata/path-data", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "fdata/objects-map", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:team-id": "~u6bd7c17d-4f59-815e-8006-5c1f6882469a", + "~:permissions": { + "~:type": "~:membership", + "~:is-owner": true, + "~:is-admin": true, + "~:can-edit": true, + "~:can-read": true, + "~:is-logged": true + }, + "~:has-media-trimmed": false, + "~:comment-thread-seqn": 0, + "~:name": "get-file-empty-lines", + "~:revn": 42, + "~:modified-at": "~m1762249418607", + "~:vern": 0, + "~:id": "~u58c5cc60-d124-81bd-8007-0ecbaf9da983", + "~:is-shared": false, + "~:migrations": { + "~#ordered-set": [ + "legacy-2", + "legacy-3", + "legacy-5", + "legacy-6", + "legacy-7", + "legacy-8", + "legacy-9", + "legacy-10", + "legacy-11", + "legacy-12", + "legacy-13", + "legacy-14", + "legacy-16", + "legacy-17", + "legacy-18", + "legacy-19", + "legacy-25", + "legacy-26", + "legacy-27", + "legacy-28", + "legacy-29", + "legacy-31", + "legacy-32", + "legacy-33", + "legacy-34", + "legacy-36", + "legacy-37", + "legacy-38", + "legacy-39", + "legacy-40", + "legacy-41", + "legacy-42", + "legacy-43", + "legacy-44", + "legacy-45", + "legacy-46", + "legacy-47", + "legacy-48", + "legacy-49", + "legacy-50", + "legacy-51", + "legacy-52", + "legacy-53", + "legacy-54", + "legacy-55", + "legacy-56", + "legacy-57", + "legacy-59", + "legacy-62", + "legacy-65", + "legacy-66", + "legacy-67", + "0001-remove-tokens-from-groups", + "0002-normalize-bool-content-v2", + "0002-clean-shape-interactions", + "0003-fix-root-shape", + "0003-convert-path-content-v2", + "0004-clean-shadow-color", + "0005-deprecate-image-type", + "0006-fix-old-texts-fills", + "0008-fix-library-colors-v4", + "0009-clean-library-colors", + "0009-add-partial-text-touched-flags", + "0010-fix-swap-slots-pointing-non-existent-shapes", + "0011-fix-invalid-text-touched-flags", + "0012-fix-position-data", + "0013-fix-component-path", + "0013-clear-invalid-strokes-and-fills", + "0014-fix-tokens-lib-duplicate-ids", + "0014-clear-components-nil-objects", + "0015-fix-text-attrs-blank-strings", + "0016-copy-fills-from-position-data-to-text-node" + ] + }, + "~:version": 67, + "~:project-id": "~u6bd7c17d-4f59-815e-8006-5c1f68846e43", + "~:created-at": "~m1762247203445", + "~:backend": "legacy-db", + "~:data": { + "~:pages": [ + "~u15222a7a-d3bc-80f1-8007-0d8e166e650f" + ], + "~:pages-index": { + "~u15222a7a-d3bc-80f1-8007-0d8e166e650f": { + "~:id": "~u15222a7a-d3bc-80f1-8007-0d8e166e650f", + "~:name": "Page 1", + "~:objects": { + "~#penpot/objects-map/v2": { + "~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u15222a7a-d3bc-80f1-8007-0d8e166e650f\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u956aea6c-4e59-80cd-8007-0ed28aaab090\",\"~u956aea6c-4e59-80cd-8007-0ed28aaab08f\",\"~u956aea6c-4e59-80cd-8007-0ed28aaab08e\"]]]", + "~u956aea6c-4e59-80cd-8007-0ed28aaab08e": "[\"~#shape\",[\"^ \",\"~:y\",599.000012199947,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-height\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:key\",\"81sn4kpbwm\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"\",\"^;\",\"normal\",\"~:typography-ref-id\",null,\"~:text-transform\",\"none\",\"~:font-id\",\"sourcesanspro\",\"^8\",\"19xnuot3lpp\",\"~:font-size\",\"14\",\"~:font-weight\",\"400\",\"~:typography-ref-file\",null,\"~:font-variant-id\",\"regular\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#565251\",\"~:fill-opacity\",1]],\"~:font-family\",\"sourcesanspro\",\"~:text\",\"Select any object on the canvas or choose a layer from the list of \"],[\"^ \",\"^:\",\"\",\"^;\",\"normal\",\"^<\",null,\"^=\",\"uppercase\",\"^>\",\"sourcesanspro\",\"^8\",\"6nyk1x5695\",\"^?\",\"14\",\"^@\",\"400\",\"^A\",null,\"^B\",\"regular\",\"^C\",\"none\",\"^D\",\"0\",\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^H\",\"sourcesanspro\",\"^I\",\"Layers\"],[\"^ \",\"^:\",\"\",\"^;\",\"normal\",\"^<\",null,\"^=\",\"uppercase\",\"^>\",\"sourcesanspro\",\"^8\",\"z7cm9xwf1\",\"^?\",\"14\",\"^@\",\"400\",\"^A\",null,\"^B\",\"regular\",\"^C\",\"none\",\"^D\",\"0\",\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^H\",\"sourcesanspro\",\"^I\",\" \"],[\"^ \",\"^:\",\"\",\"^;\",\"normal\",\"^<\",null,\"^=\",\"none\",\"^>\",\"sourcesanspro\",\"^8\",\"2kkq1gh843\",\"^?\",\"14\",\"^@\",\"400\",\"^A\",null,\"^B\",\"regular\",\"^C\",\"none\",\"^D\",\"0\",\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^H\",\"sourcesanspro\",\"^I\",\"in the \"],[\"^ \",\"^:\",\"\",\"^;\",\"normal\",\"^<\",null,\"^=\",\"none\",\"^>\",\"sourcesanspro\",\"^8\",\"22pap590a8p\",\"^?\",\"14\",\"^@\",\"400\",\"^A\",null,\"^B\",\"regular\",\"^C\",\"none\",\"^D\",\"0\",\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^H\",\"sourcesanspro\",\"^I\",\"←\"],[\"^ \",\"^:\",\"\",\"^;\",\"normal\",\"^<\",null,\"^=\",\"none\",\"^>\",\"sourcesanspro\",\"^8\",\"hgie5tzklf\",\"^?\",\"14\",\"^@\",\"400\",\"^A\",null,\"^B\",\"regular\",\"^C\",\"none\",\"^D\",\"0\",\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^H\",\"sourcesanspro\",\"^I\",\" left sidebar. \"]],\"^<\",null,\"^=\",\"none\",\"~:text-align\",\"left\",\"^>\",\"sourcesanspro\",\"^8\",\"b48lv\",\"^?\",\"0\",\"^@\",\"400\",\"^A\",null,\"~:text-direction\",\"ltr\",\"^7\",\"paragraph\",\"^B\",\"regular\",\"^C\",\"none\",\"^D\",\"0\",\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^H\",\"sourcesanspro\"]]]],\"~:vertical-align\",\"\"],\"~:name\",\"text-with-empty-lines\",\"~:width\",179.99999284744285,\"^7\",\"^I\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",785.9999587189424,\"~:y\",599.000012199947]],[\"^P\",[\"^ \",\"~:x\",965.9999515663852,\"~:y\",599.000012199947]],[\"^P\",[\"^ \",\"~:x\",965.9999515663852,\"~:y\",669.0000129290239]],[\"^P\",[\"^ \",\"~:x\",785.9999587189424,\"~:y\",669.0000129290239]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u15222a7a-d3bc-80f1-8007-0d8e166e650f\",\"~:id\",\"~u956aea6c-4e59-80cd-8007-0ed28aaab08e\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \"],\"~:position-data\",[[\"^ \",\"~:y\",616.4999978374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"400\",\"~:y1\",-1,\"^N\",156.859375,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",785.9999919000137,\"~:x1\",0,\"~:y2\",17.5,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"~:x2\",156.859375,\"~:direction\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"~:height\",18.5,\"^I\",\"Select any object on the \"],[\"^ \",\"~:y\",633.2968728374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"400\",\"^W\",15.796875,\"^N\",158.34375,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",785.9999919000137,\"^X\",0,\"^Y\",34.296875,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",158.34375,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\"canvas or choose a layer \"],[\"^ \",\"~:y\",650.0937478374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"400\",\"^W\",32.59375,\"^N\",95.1953125,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",785.9999919000137,\"^X\",0,\"^Y\",51.09375,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",95.1953125,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\"from the list of \"],[\"^ \",\"~:y\",650.0937478374983,\"^;\",\"normal\",\"^=\",\"uppercase\",\"^?\",\"14px\",\"^@\",\"700\",\"^W\",32.59375,\"^N\",49.7265625,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",881.1953044000137,\"^X\",95.1953125,\"^Y\",51.09375,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",144.921875,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\"Layers\"],[\"^ \",\"~:y\",650.0937478374983,\"^;\",\"normal\",\"^=\",\"uppercase\",\"^?\",\"14px\",\"^@\",\"400\",\"^W\",32.59375,\"^N\",3.53125,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",930.9218669000137,\"^X\",144.921875,\"^Y\",51.09375,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",148.453125,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\" \"],[\"^ \",\"~:y\",650.0937478374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"400\",\"^W\",32.59375,\"^N\",14.5234375,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",934.4531169000137,\"^X\",148.453125,\"^Y\",51.09375,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",162.9765625,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\"in \"],[\"^ \",\"~:y\",666.8906228374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"400\",\"^W\",49.390625,\"^N\",24.4140625,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",785.9999919000137,\"^X\",0,\"^Y\",67.890625,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",24.4140625,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\"the \"],[\"^ \",\"~:y\",666.8906228374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"700\",\"^W\",49.390625,\"^N\",13.8046875,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",810.4140544000137,\"^X\",24.4140625,\"^Y\",67.890625,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",38.21875,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\"←\"],[\"^ \",\"~:y\",666.8906228374983,\"^;\",\"normal\",\"^=\",\"none\",\"^?\",\"14px\",\"^@\",\"400\",\"^W\",49.390625,\"^N\",80.3984375,\"^C\",\"none solid rgb(86, 82, 81)\",\"^D\",\"-0.2px\",\"~:x\",824.2187419000137,\"^X\",38.21875,\"^Y\",67.890625,\"^E\",[[\"^ \",\"^F\",\"#565251\",\"^G\",1]],\"^Z\",118.6171875,\"^[\",\"ltr\",\"^H\",\"\\\"DM Sans\\\"\",\"^10\",18.5,\"^I\",\" left sidebar. \"]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",785.9999587189424,\"~:blocked\",false,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",785.9999587189424,\"~:y\",599.000012199947,\"^N\",179.99999284744285,\"^10\",70.00000072907687,\"^X\",785.9999587189424,\"^W\",599.000012199947,\"^Z\",965.9999515663852,\"^Y\",669.0000129290239]],\"^E\",[],\"~:flip-x\",null,\"^10\",70.00000072907687,\"~:flip-y\",null]]", + "~u956aea6c-4e59-80cd-8007-0ed28aaab08f": "[\"~#shape\",[\"^ \",\"~:y\",702.000011765276,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-height\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:font-style\",\"normal\",\"^8\",[[\"^ \",\"~:text\",\"\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#565251\",\"~:fill-opacity\",1]],\"~:font-id\",\"sourcesanspro\",\"~:font-family\",\"sourcesanspro\",\"~:font-variant-id\",\"regular\",\"~:font-weight\",\"400\",\"^9\",\"normal\",\"~:letter-spacing\",\"0\"]],\"^>\",\"sourcesanspro\",\"~:key\",\"rakh\",\"^A\",\"400\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\"],[\"^ \",\"^9\",\"normal\",\"^8\",[[\"^ \",\"^:\",\"\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^>\",\"sourcesanspro\",\"^?\",\"sourcesanspro\",\"^@\",\"regular\",\"^A\",\"400\",\"^9\",\"normal\",\"^B\",\"0\"]],\"^>\",\"sourcesanspro\",\"^C\",\"3n2nr\",\"^A\",\"400\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\"],[\"^ \",\"~:line-height\",\"1.2\",\"^9\",\"normal\",\"^8\",[[\"^ \",\"^D\",\"1.2\",\"^9\",\"normal\",\"~:text-transform\",\"none\",\"^>\",\"sourcesanspro\",\"~:font-size\",\"14\",\"^A\",\"400\",\"^@\",\"regular\",\"~:text-decoration\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\",\"^:\",\"In the \"],[\"^ \",\"^D\",\"1.2\",\"^9\",\"normal\",\"^E\",\"uppercase\",\"^>\",\"sourcesanspro\",\"^F\",\"14\",\"^A\",\"400\",\"^@\",\"regular\",\"^G\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\",\"^:\",\"TOKENS\"],[\"^ \",\"^D\",\"1.2\",\"^9\",\"normal\",\"^E\",\"uppercase\",\"^>\",\"sourcesanspro\",\"^F\",\"14\",\"^A\",\"400\",\"^@\",\"regular\",\"^G\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\",\"^:\",\" \"],[\"^ \",\"^D\",\"1.2\",\"^9\",\"normal\",\"^E\",\"none\",\"^>\",\"sourcesanspro\",\"^F\",\"14\",\"^A\",\"400\",\"^@\",\"regular\",\"^G\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\",\"^:\",\"tab, right click any design token to show the token menu. There you can see how the token can be applied to your selected layer.\"]],\"^E\",\"none\",\"^>\",\"sourcesanspro\",\"^C\",\"7usjj\",\"^F\",\"14\",\"^A\",\"400\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^G\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\"]]]],\"^;\",[]],\"~:name\",\"text-with-empty-lines-2\",\"~:width\",179.99999284744263,\"^7\",\"^:\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",785.9999587189404,\"~:y\",702.000011765276]],[\"^K\",[\"^ \",\"~:x\",965.9999515663831,\"~:y\",702.000011765276]],[\"^K\",[\"^ \",\"~:x\",965.9999515663831,\"~:y\",804.0000067346009]],[\"^K\",[\"^ \",\"~:x\",785.9999587189404,\"~:y\",804.0000067346009]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u15222a7a-d3bc-80f1-8007-0d8e166e650f\",\"~:id\",\"~u956aea6c-4e59-80cd-8007-0ed28aaab08f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"layerBase.text\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",719.5036141705059,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"~:y1\",-0.5333404541015625,\"^I\",38.81666564941406,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"~:x1\",0,\"~:y2\",17.333328247070312,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"~:x2\",38.81666564941406,\"~:direction\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"~:height\",17.866668701171875,\"^:\",\"In the \"]],[\"^S\",[\"^ \",\"~:y\",719.5036141705059,\"^9\",\"normal\",\"^E\",\"uppercase\",\"^F\",\"14px\",\"^A\",\"700\",\"^T\",-0.5333404541015625,\"^I\",54.93333435058594,\"^G\",\"none\",\"^B\",\"normal\",\"~:x\",825.303229815053,\"^U\",38.81666564941406,\"^V\",17.333328247070312,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",93.75,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"TOKENS\"]],[\"^S\",[\"^ \",\"~:y\",719.5036141705059,\"^9\",\"normal\",\"^E\",\"uppercase\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",-0.5333404541015625,\"^I\",3.51666259765625,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",880.2365641656389,\"^U\",93.75,\"^V\",17.333328247070312,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",97.26666259765625,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\" \"]],[\"^S\",[\"^ \",\"~:y\",736.3036172222637,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",16.26666259765625,\"^I\",162.96665954589844,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"^U\",0,\"^V\",34.133331298828125,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",162.96665954589844,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"tab, right click any design \"]],[\"^S\",[\"^ \",\"~:y\",753.1036202740215,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",33.06666564941406,\"^I\",154.86666870117188,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"^U\",0,\"^V\",50.93333435058594,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",154.86666870117188,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"token to show the token \"]],[\"^S\",[\"^ \",\"~:y\",769.9036233257793,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",49.866668701171875,\"^I\",159.73333740234375,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"^U\",0,\"^V\",67.73333740234375,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",159.73333740234375,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"menu. There you can see \"]],[\"^S\",[\"^ \",\"~:y\",786.7036263775371,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",66.66667175292969,\"^I\",139.11666870117188,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"^U\",0,\"^V\",84.53334045410156,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",139.11666870117188,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"how the token can be \"]],[\"^S\",[\"^ \",\"~:y\",803.5036141705059,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",83.46665954589844,\"^I\",156.25,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"^U\",0,\"^V\",101.33332824707031,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",156.25,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"applied to your selected \"]],[\"^S\",[\"^ \",\"~:y\",820.3036172222637,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^T\",100.26666259765625,\"^I\",31.76666259765625,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.4865641656389,\"^U\",0,\"^V\",118.13333129882812,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^W\",31.76666259765625,\"^X\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^Y\",17.866668701171875,\"^:\",\"layer.\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",785.9999587189404,\"~:blocked\",false,\"~:selrect\",[\"^S\",[\"^ \",\"~:x\",785.9999587189404,\"~:y\",702.000011765276,\"^I\",179.99999284744263,\"^Y\",101.99999496932492,\"^U\",785.9999587189404,\"^T\",702.000011765276,\"^W\",965.9999515663831,\"^V\",804.0000067346009]],\"^;\",[],\"~:flip-x\",null,\"^Y\",101.99999496932492,\"~:flip-y\",null]]", + "~u956aea6c-4e59-80cd-8007-0ed28aaab090": "[\"~#shape\",[\"^ \",\"~:y\",841.000011432478,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-height\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:font-style\",\"normal\",\"^8\",[[\"^ \",\"~:text\",\"\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#565251\",\"~:fill-opacity\",1]],\"~:font-id\",\"sourcesanspro\",\"~:font-family\",\"sourcesanspro\",\"~:font-variant-id\",\"regular\",\"~:font-weight\",\"400\",\"^9\",\"normal\",\"~:letter-spacing\",\"0\"]],\"^>\",\"sourcesanspro\",\"~:key\",\"rakh\",\"^A\",\"400\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\"],[\"^ \",\"^9\",\"normal\",\"^8\",[[\"^ \",\"^:\",\"\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^>\",\"sourcesanspro\",\"^?\",\"sourcesanspro\",\"^@\",\"regular\",\"^A\",\"400\",\"^9\",\"normal\",\"^B\",\"0\"]],\"^>\",\"sourcesanspro\",\"^C\",\"3n2nr\",\"^A\",\"400\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\"],[\"^ \",\"~:line-height\",\"1.2\",\"^9\",\"normal\",\"^8\",[[\"^ \",\"^D\",\"1.2\",\"^9\",\"normal\",\"~:text-transform\",\"none\",\"^>\",\"sourcesanspro\",\"~:font-size\",\"14\",\"^A\",\"400\",\"^@\",\"regular\",\"~:text-decoration\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\",\"^:\",\"Check/uncheck the property names to apply/remove the token from the properties of your selected layer.\"]],\"^E\",\"none\",\"^>\",\"sourcesanspro\",\"^C\",\"7usjj\",\"^F\",\"14\",\"^A\",\"400\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^G\",\"none\",\"^B\",\"0\",\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^?\",\"sourcesanspro\"]]]],\"^;\",[]],\"~:name\",\"text-with-empty-lines-3\",\"~:width\",179.99999284744263,\"^7\",\"^:\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",785.9999587189404,\"~:y\",841.000011432478]],[\"^K\",[\"^ \",\"~:x\",965.9999515663831,\"~:y\",841.000011432478]],[\"^K\",[\"^ \",\"~:x\",965.9999515663831,\"~:y\",909.0000123861524]],[\"^K\",[\"^ \",\"~:x\",785.9999587189404,\"~:y\",909.0000123861524]]],\"~:layout-item-h-sizing\",\"~:fill\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u15222a7a-d3bc-80f1-8007-0d8e166e650f\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u956aea6c-4e59-80cd-8007-0ed28aaab090\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"^M\",\"layerBase.text\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",858.0036384892012,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"~:y1\",-0.5333404541015625,\"^I\",126.98333740234375,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.8198161187639,\"~:x1\",0,\"~:y2\",17.333328247070312,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"~:x2\",126.98333740234375,\"~:direction\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"~:height\",17.866668701171875,\"^:\",\"Check/uncheck the \"]],[\"^X\",[\"^ \",\"~:y\",874.803641540959,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^Y\",16.26666259765625,\"^I\",160.88333129882812,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.8198161187639,\"^Z\",0,\"^[\",34.133331298828125,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^10\",160.88333129882812,\"^11\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^12\",17.866668701171875,\"^:\",\"property names to apply/\"]],[\"^X\",[\"^ \",\"~:y\",891.6036445927168,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^Y\",33.06666564941406,\"^I\",171.14999389648438,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.8198161187639,\"^Z\",0,\"^[\",50.93333435058594,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^10\",171.14999389648438,\"^11\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^12\",17.866668701171875,\"^:\",\"remove the token from the \"]],[\"^X\",[\"^ \",\"~:y\",908.4036476444746,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^Y\",49.866668701171875,\"^I\",116.71665954589844,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.8198161187639,\"^Z\",0,\"^[\",67.73333740234375,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^10\",116.71665954589844,\"^11\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^12\",17.866668701171875,\"^:\",\"properties of your \"]],[\"^X\",[\"^ \",\"~:y\",925.2036506962324,\"^9\",\"normal\",\"^E\",\"none\",\"^F\",\"14px\",\"^A\",\"400\",\"^Y\",66.66667175292969,\"^I\",89.51666259765625,\"^G\",\"none\",\"^B\",\"-0.2px\",\"~:x\",786.8198161187639,\"^Z\",0,\"^[\",84.53334045410156,\"^;\",[[\"^ \",\"^<\",\"#565251\",\"^=\",1]],\"^10\",89.51666259765625,\"^11\",\"ltr\",\"^?\",\"\\\"DM Sans\\\"\",\"^12\",17.866668701171875,\"^:\",\"selected layer.\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",785.9999587189404,\"~:blocked\",false,\"~:selrect\",[\"^X\",[\"^ \",\"~:x\",785.9999587189404,\"~:y\",841.000011432478,\"^I\",179.99999284744263,\"^12\",68.00000095367443,\"^Z\",785.9999587189404,\"^Y\",841.000011432478,\"^10\",965.9999515663831,\"^[\",909.0000123861524]],\"^;\",[],\"~:flip-x\",null,\"^12\",68.00000095367443,\"~:flip-y\",null]]" + } + } + } + }, + "~:id": "~u58c5cc60-d124-81bd-8007-0ecbaf9da983", + "~:options": { + "~:components-v2": true, + "~:base-font-size": "16px" + } + } +} \ No newline at end of file diff --git a/frontend/playwright/ui/render-wasm-specs/texts.spec.js b/frontend/playwright/ui/render-wasm-specs/texts.spec.js index 7c7f33da29..56f593104f 100644 --- a/frontend/playwright/ui/render-wasm-specs/texts.spec.js +++ b/frontend/playwright/ui/render-wasm-specs/texts.spec.js @@ -367,6 +367,26 @@ test("Renders a file with texts with tabs", async ({ await expect(workspace.canvas).toHaveScreenshot(); }); +test("Renders a file with texts with empty lines", async ({ + page, +}) => { + const workspace = new WasmWorkspacePage(page); + await workspace.setupEmptyFile(); + await workspace.mockGetFile("render-wasm/get-file-empty-lines.json"); + + await workspace.goToWorkspace({ + id: "58c5cc60-d124-81bd-8007-0ecbaf9da983", + pageId: "15222a7a-d3bc-80f1-8007-0d8e166e650f", + }); + + await workspace.waitForFirstRender({ hideUI: false }); + await workspace.clickLeafLayer("text-with-empty-lines-2"); + await workspace.hideUI(); + await workspace.page.keyboard.press("Enter"); + + await expect(workspace.canvas).toHaveScreenshot(); +}); + test.skip("Updates text alignment edition - part 1", async ({ page }) => { const workspace = new WasmWorkspacePage(page); await workspace.setupEmptyFile(); diff --git a/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-texts-with-empty-lines-1.png b/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-texts-with-empty-lines-1.png new file mode 100644 index 0000000000..ca87b05546 Binary files /dev/null and b/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-texts-with-empty-lines-1.png differ diff --git a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss index f1ba49ac36..86856063c5 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss +++ b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss @@ -35,15 +35,10 @@ } [data-itype="inline"] { - display: inline-block; + display: inline; line-break: auto; line-height: inherit; caret-color: var(--text-editor-caret-color); - - // firefox-only - white-space: preserve-spaces; - - // others white-space-collapse: pre; tab-size: 2; -o-tab-size: 2; diff --git a/frontend/src/app/util/text/content/to_dom.cljs b/frontend/src/app/util/text/content/to_dom.cljs index 9b38939aa9..7c7b8af6b7 100644 --- a/frontend/src/app/util/text/content/to_dom.cljs +++ b/frontend/src/app/util/text/content/to_dom.cljs @@ -99,8 +99,9 @@ (dissoc styles :line-height))) (defn get-inline-children - [inline] - [(if (= "" (:text inline)) + [inline paragraph] + [(if (and (= "" (:text inline)) + (= 1 (count (:children paragraph)))) (dom/create-element "br") (dom/create-text (:text inline)))]) @@ -108,6 +109,17 @@ [] (.toString (.floor js/Math (* (.random js/Math) (.-MAX_SAFE_INTEGER js/Number))) 36)) +(defn has-content? + [paragraph] + (some #(not= "" (:text % "")) (:children paragraph))) + +(defn should-filter-empty-paragraph? + [paragraphs index] + (and (not (has-content? (nth paragraphs index))) + (< index (count paragraphs)) + (some has-content? (drop (inc index) paragraphs)) + (every? #(not (has-content? %)) (take (inc index) paragraphs)))) + (defn create-inline [inline paragraph] (create-element @@ -115,7 +127,7 @@ {:id (or (:key inline) (create-random-key)) :data {:itype "inline"} :style (get-inline-styles inline paragraph)} - (get-inline-children inline))) + (get-inline-children inline paragraph))) (defn create-paragraph [paragraph] @@ -128,10 +140,15 @@ (defn create-root [root] - (let [root-styles (get-root-styles root)] + (let [root-styles (get-root-styles root) + paragraphs (get-in root [:children 0 :children]) + filtered-paragraphs (->> paragraphs + (map-indexed vector) + (remove (fn [[index _]] (should-filter-empty-paragraph? paragraphs index))) + (mapv second))] (create-element "div" {:id (or (:key root) (create-random-key)) :data {:itype "root"} :style root-styles} - (mapv create-paragraph (get-in root [:children 0 :children]))))) + (mapv create-paragraph filtered-paragraphs)))) diff --git a/render-wasm/src/render/text.rs b/render-wasm/src/render/text.rs index da6974eaa3..5ca7a4cfdf 100644 --- a/render-wasm/src/render/text.rs +++ b/render-wasm/src/render/text.rs @@ -205,10 +205,9 @@ fn draw_text( paragraph_builder_groups: &mut [Vec], ) { let text_content = shape.get_text_content(); - // FIXME: this does not always return the height we need - // let text_height = text_content.size.height; - let text_width = text_content.get_width(); - let text_height = text_content.get_height(text_width); + let selrect_width = shape.selrect().width(); + let text_width = text_content.get_width(selrect_width); + let text_height = text_content.get_height(selrect_width); let selrect_height = shape.selrect().height(); let mut global_offset_y = match shape.vertical_align() { VerticalAlign::Center => (selrect_height - text_height) / 2.0, diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs index aa34dc0a8b..c83e009052 100644 --- a/render-wasm/src/shapes.rs +++ b/render-wasm/src/shapes.rs @@ -330,7 +330,7 @@ impl Shape { self.selrect.set_ltrb(left, top, right, bottom); if let Type::Text(ref mut text) = self.shape_type { text.update_layout(self.selrect); - text.set_xywh(left, top, right - left, bottom - top); + text.set_xywh(left, top, self.selrect.width(), self.selrect.height()); } } diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index 1e28bdf5ca..ada61b152d 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -403,13 +403,14 @@ impl TextContent { let mut paragraph_builders = self.paragraph_builder_group_from_text(None); let paragraphs = self.build_paragraphs_from_paragraph_builders(&mut paragraph_builders, f32::MAX); + let (width, height) = paragraphs .iter() .flatten() .fold((0.0, 0.0), |(auto_width, auto_height), paragraph| { ( - f32::max(paragraph.max_intrinsic_width(), auto_width), + f32::max(paragraph.longest_line(), auto_width), auto_height + paragraph.height(), ) }); @@ -452,11 +453,11 @@ impl TextContent { TextContentLayoutResult(paragraph_builders, paragraphs, size) } - pub fn get_width(&self) -> f32 { + pub fn get_width(&self, width: f32) -> f32 { if self.grow_type() == GrowType::AutoWidth { self.size.width } else { - self.bounds.width() + width } } @@ -599,7 +600,6 @@ impl Paragraph { self.line_height } - // FIXME: move serialization to wasm module pub fn paragraph_to_style(&self) -> ParagraphStyle { let mut style = ParagraphStyle::default(); @@ -711,7 +711,7 @@ impl TextSpan { style.set_font_families(&font_families); style.set_font_size(self.font_size); style.set_letter_spacing(self.letter_spacing); - style.set_half_leading(true); + style.set_half_leading(false); style } @@ -753,12 +753,18 @@ impl TextSpan { format!("{}", self.font_family) } + fn remove_ignored_chars(text: &str) -> String { + text.chars() + .filter(|&c| c >= '\u{0020}' && c != '\u{2028}' && c != '\u{2029}') + .collect() + } + pub fn apply_text_transform(&self) -> String { + let text = Self::remove_ignored_chars(&self.text); match self.text_transform { - Some(TextTransform::Uppercase) => self.text.to_uppercase(), - Some(TextTransform::Lowercase) => self.text.to_lowercase(), - Some(TextTransform::Capitalize) => self - .text + Some(TextTransform::Uppercase) => text.to_uppercase(), + Some(TextTransform::Lowercase) => text.to_lowercase(), + Some(TextTransform::Capitalize) => text .split_whitespace() .map(|word| { let mut chars = word.chars(); @@ -769,7 +775,7 @@ impl TextSpan { }) .collect::>() .join(" "), - None => self.text.clone(), + None => text, } }