ranger-compiler 3.5.1 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1064 -20
- package/LICENSE +3 -1
- package/README.md +123 -28
- package/dist/Lang.rgr +1188 -290
- package/dist/api.d.ts +2343 -879
- package/dist/api.js +79923 -56921
- package/dist/lib/JSON.rgr +102 -91
- package/dist/lib/Shell.rgr +4 -4
- package/dist/lib/apple/AppleToolchain.rgr +4 -4
- package/dist/lib/apple/README.md +5 -4
- package/dist/lib/apple/apple_test.rgr +1 -1
- package/dist/lib/core/README.md +1 -1
- package/dist/lib/evg/EVG.rgr +12 -0
- package/dist/lib/evg/EVGA11yFromTree.rgr +302 -0
- package/dist/lib/evg/EVGA11yTree.rgr +894 -0
- package/dist/lib/evg/EVGBox.rgr +267 -0
- package/dist/lib/evg/EVGBoxShorthandTest.rgr +220 -0
- package/dist/lib/evg/EVGCodepoint.rgr +316 -0
- package/dist/lib/evg/EVGColor.rgr +700 -0
- package/dist/lib/evg/EVGCommands.rgr +177 -0
- package/dist/lib/evg/EVGComponent.rgr +331 -0
- package/dist/lib/evg/EVGComponentTest.rgr +387 -0
- package/dist/lib/evg/EVGConnector.rgr +541 -0
- package/dist/lib/evg/EVGConnectorTest.rgr +306 -0
- package/dist/lib/evg/EVGDisplayList.rgr +4186 -0
- package/dist/lib/evg/EVGEasing.rgr +370 -0
- package/dist/lib/evg/EVGEffectTest.rgr +253 -0
- package/dist/lib/evg/EVGElement.rgr +4914 -0
- package/dist/lib/evg/EVGFixedTest.rgr +289 -0
- package/dist/lib/evg/EVGFlexRulesTest.rgr +317 -0
- package/dist/lib/evg/EVGFlexWrapTest.rgr +246 -0
- package/dist/lib/evg/EVGFling.rgr +244 -0
- package/dist/lib/evg/EVGFocus.rgr +400 -0
- package/dist/lib/evg/EVGFocusTest.rgr +399 -0
- package/dist/lib/evg/EVGGradient.rgr +322 -0
- package/dist/lib/evg/EVGGrapheme.rgr +190 -0
- package/dist/lib/evg/EVGGrid.rgr +975 -0
- package/dist/lib/evg/EVGHitTest.rgr +208 -0
- package/dist/lib/evg/EVGHoles.rgr +294 -0
- package/dist/lib/evg/EVGHostMeasurerTest.rgr +281 -0
- package/dist/lib/evg/EVGHostTextMeasurer.rgr +331 -0
- package/dist/lib/evg/EVGHostTree.rgr +834 -0
- package/dist/lib/evg/EVGHostTreeTest.rgr +447 -0
- package/dist/lib/evg/EVGImageDecode.rgr +117 -0
- package/dist/lib/evg/EVGImageMeasurer.rgr +86 -0
- package/dist/lib/evg/EVGInspect.rgr +883 -0
- package/dist/lib/evg/EVGInvalidateTest.rgr +432 -0
- package/dist/lib/evg/EVGJsonTest.rgr +535 -0
- package/dist/lib/evg/EVGLayout.rgr +4220 -0
- package/dist/lib/evg/EVGMeasure.rgr +1267 -0
- package/dist/lib/evg/EVGOverlayTest.rgr +626 -0
- package/dist/lib/evg/EVGPatch.rgr +1721 -0
- package/dist/lib/evg/EVGPatchTest.rgr +692 -0
- package/dist/lib/evg/EVGPopoverTest.rgr +395 -0
- package/dist/lib/evg/EVGReconcile.rgr +226 -0
- package/dist/lib/evg/EVGReconcileTest.rgr +421 -0
- package/dist/lib/evg/EVGReject.rgr +126 -0
- package/dist/lib/evg/EVGRelayoutTest.rgr +375 -0
- package/dist/lib/evg/EVGRtlLayoutTest.rgr +319 -0
- package/dist/lib/evg/EVGRuler.rgr +232 -0
- package/dist/lib/evg/EVGRulerTest.rgr +172 -0
- package/dist/lib/evg/EVGSelectChrome.rgr +178 -0
- package/dist/lib/evg/EVGStyleCacheTest.rgr +419 -0
- package/dist/lib/evg/EVGStyleSheet.rgr +2148 -0
- package/dist/lib/evg/EVGStyleStateTest.rgr +407 -0
- package/dist/lib/evg/EVGStyleVarTest.rgr +471 -0
- package/dist/lib/evg/EVGText.rgr +105 -0
- package/dist/lib/evg/EVGTextEngine.rgr +536 -0
- package/dist/lib/evg/EVGTextMeasurer.rgr +720 -0
- package/dist/lib/evg/EVGTimingTest.rgr +1417 -0
- package/dist/lib/evg/EVGToolbar.rgr +1369 -0
- package/dist/lib/evg/EVGTransition.rgr +728 -0
- package/dist/lib/evg/EVGTreeJson.rgr +721 -0
- package/dist/lib/evg/EVGUnit.rgr +554 -0
- package/dist/lib/evg/EVGViewportUnitTest.rgr +236 -0
- package/dist/lib/evg/EvgApp.rgr +189 -0
- package/dist/lib/evg/EvgBitmapTracer.rgr +4277 -0
- package/dist/lib/evg/EvgBitmapTracerTest.rgr +2119 -0
- package/dist/lib/evg/EvgHost.rgr +451 -0
- package/dist/lib/evg/EvgTest.rgr +91 -0
- package/dist/lib/evg/EvgTraceColor.rgr +236 -0
- package/dist/lib/evg/EvgTraceCurve.rgr +648 -0
- package/dist/lib/evg/EvgTraceFit.rgr +767 -0
- package/dist/lib/evg/EvgTracePath.rgr +435 -0
- package/dist/lib/evg/EvgTraceTypes.rgr +559 -0
- package/dist/lib/evg/EvgViewport.rgr +313 -0
- package/dist/lib/evg/FxDemoDoc.rgr +185 -0
- package/dist/lib/evg/HOSTS.md +227 -0
- package/dist/lib/evg/ISSUES.md +835 -0
- package/dist/lib/evg/PLAN_ACCESSIBILITY.md +650 -0
- package/dist/lib/evg/PLAN_CSS_LAYOUT_AND_FONTS.md +1124 -0
- package/dist/lib/evg/PLAN_EFFECTS.md +431 -0
- package/dist/lib/evg/PLAN_EVG.md +518 -0
- package/dist/lib/evg/PLAN_EVG_RENDERER.md +1674 -0
- package/dist/lib/evg/PLAN_INSPECTOR.md +788 -0
- package/dist/lib/evg/PLAN_LINKS_AND_FORMS.md +157 -0
- package/dist/lib/evg/PLAN_NATIVE_HOSTS.md +671 -0
- package/dist/lib/evg/PLAN_VECTOR_IR.md +664 -0
- package/dist/lib/evg/PLAN_VIEW_TRANSFORM.md +322 -0
- package/dist/lib/evg/PathBuilder.rgr +333 -0
- package/dist/lib/evg/README.md +1236 -0
- package/dist/lib/evg/SPEC.md +1252 -0
- package/dist/lib/evg/SVGPathParser.rgr +1199 -0
- package/dist/lib/evg/SvgParser.rgr +1736 -0
- package/dist/lib/evg/TODO_EVG_RENDERER.md +595 -0
- package/dist/lib/evg/VectorShapes.rgr +331 -0
- package/dist/lib/evg/VectorStroke.rgr +107 -0
- package/dist/lib/evg/VectorViewBox.rgr +380 -0
- package/dist/lib/evg/agent/README.md +290 -0
- package/dist/lib/evg/agent/evg_agent.rgr +899 -0
- package/dist/lib/evg/agent/fixtures/broken.evg.json +7 -0
- package/dist/lib/evg/agent/fixtures/card.evg.json +9 -0
- package/dist/lib/evg/agent/fixtures/connector.css +63 -0
- package/dist/lib/evg/agent/fixtures/connector.evg.json +14 -0
- package/dist/lib/evg/agent/fixtures/drawn.evg.json +129 -0
- package/dist/lib/evg/agent/fixtures/gradient.evg.json +4 -0
- package/dist/lib/evg/agent/fixtures/popover.css +99 -0
- package/dist/lib/evg/agent/fixtures/popover.evg.json +30 -0
- package/dist/lib/evg/agent/roundtrip.sh +74 -0
- package/dist/lib/evg/agent/smoke.sh +230 -0
- package/dist/lib/evg/android/README.md +97 -0
- package/dist/lib/evg/android/androidstubs/AndroidStubs.kt +175 -0
- package/dist/lib/evg/android/androidstubs/Annotation.kt +10 -0
- package/dist/lib/evg/android/androidstubs/App.kt +30 -0
- package/dist/lib/evg/android/androidstubs/Content.kt +41 -0
- package/dist/lib/evg/android/androidstubs/ContentRes.kt +12 -0
- package/dist/lib/evg/android/androidstubs/InputMethod.kt +46 -0
- package/dist/lib/evg/android/androidstubs/Net.kt +6 -0
- package/dist/lib/evg/android/androidstubs/Os.kt +30 -0
- package/dist/lib/evg/android/androidstubs/Util.kt +15 -0
- package/dist/lib/evg/android/androidstubs/View.kt +113 -0
- package/dist/lib/evg/android/androidstubs/Widget.kt +16 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidEvgSurface.kt +323 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidTextMeasurer.kt +56 -0
- package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/RippleEffect.kt +262 -0
- package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtEvgSurface.kt +238 -0
- package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtTextMeasurer.kt +85 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgEngineThread.kt +115 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgPainter.kt +231 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgSurface.kt +117 -0
- package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/RecordingSurface.kt +94 -0
- package/dist/lib/evg/apple/README.md +128 -0
- package/dist/lib/evg/apple/Sources/CoreGraphicsEvgSurface.swift +329 -0
- package/dist/lib/evg/apple/Sources/CoreTextMeasurer.swift +70 -0
- package/dist/lib/evg/apple/Sources/EvgEngineQueue.swift +105 -0
- package/dist/lib/evg/apple/Sources/EvgPainter.swift +225 -0
- package/dist/lib/evg/apple/Sources/EvgSurface.swift +163 -0
- package/dist/lib/evg/apple/Sources/RecordingSurface.swift +110 -0
- package/dist/lib/evg/bench/EvgLayoutBench.rgr +34 -0
- package/dist/lib/evg/bench/README.md +64 -0
- package/dist/lib/evg/bench/layout-bench.mjs +316 -0
- package/dist/lib/evg/bench/layout-cases.mjs +510 -0
- package/dist/lib/evg/bench/layout-conformance.mjs +254 -0
- package/dist/lib/evg/bin/.gitignore +17 -0
- package/dist/lib/evg/evg_test.rgr +313 -0
- package/dist/lib/evg/gl/README.md +198 -0
- package/dist/lib/evg/gl/a11y-paint-check.mjs +73 -0
- package/dist/lib/evg/gl/blur-check.mjs +399 -0
- package/dist/lib/evg/gl/boxmodel.json +1 -0
- package/dist/lib/evg/gl/demo.html +46 -0
- package/dist/lib/evg/gl/effect-presets.css +285 -0
- package/dist/lib/evg/gl/effect-presets.js +63 -0
- package/dist/lib/evg/gl/effect-shots.mjs +135 -0
- package/dist/lib/evg/gl/evg-a11y.js +566 -0
- package/dist/lib/evg/gl/evg-binary.js +160 -0
- package/dist/lib/evg/gl/evg-engine.js +296 -0
- package/dist/lib/evg/gl/evg-fx.js +237 -0
- package/dist/lib/evg/gl/evg-gestures.js +209 -0
- package/dist/lib/evg/gl/evg-list.js +167 -0
- package/dist/lib/evg/gl/evg-measure.js +186 -0
- package/dist/lib/evg/gl/evg-textinput.js +303 -0
- package/dist/lib/evg/gl/evg-view.js +144 -0
- package/dist/lib/evg/gl/evg-webgl.js +3942 -0
- package/dist/lib/evg/gl/fx-check.mjs +998 -0
- package/dist/lib/evg/gl/fx-demo.html +166 -0
- package/dist/lib/evg/gl/fx-demo.js +2 -0
- package/dist/lib/evg/gl/fx-serve.mjs +47 -0
- package/dist/lib/evg/gl/gestures-check.mjs +189 -0
- package/dist/lib/evg/gl/list-binary-check.mjs +152 -0
- package/dist/lib/evg/gl/measure-check.mjs +135 -0
- package/dist/lib/evg/gl/rotation-check.mjs +207 -0
- package/dist/lib/evg/gl/shift-check.mjs +113 -0
- package/dist/lib/evg/gl/stroke-check.mjs +168 -0
- package/dist/lib/evg/gl/text-snap-check.mjs +139 -0
- package/dist/lib/evg/gl/view-check.mjs +343 -0
- package/dist/lib/evg/gl/view-policy-check.mjs +184 -0
- package/dist/lib/evg/html/evg-dom.js +318 -0
- package/dist/lib/evg/html/evg-html.js +600 -0
- package/dist/lib/evg/inspect/README.md +415 -0
- package/dist/lib/evg/inspect/browser-smoke.mjs +115 -0
- package/dist/lib/evg/inspect/evg-inspect.js +947 -0
- package/dist/lib/evg/inspect/shots/css.png +0 -0
- package/dist/lib/evg/inspect/shots/dashboard.png +0 -0
- package/dist/lib/evg/inspect/shots/pptx-slide.png +0 -0
- package/dist/lib/evg/inspect/shots/state.png +0 -0
- package/dist/lib/evg/inspect/shots.mjs +226 -0
- package/dist/lib/evg/oracle/css-blur.json +576 -0
- package/dist/lib/evg/oracle/css-box.json +157 -0
- package/dist/lib/evg/oracle/css-timing.json +709 -0
- package/dist/lib/evg/oracle/css_blur_oracle.mjs +529 -0
- package/dist/lib/evg/oracle/css_box_oracle.mjs +106 -0
- package/dist/lib/evg/oracle/css_timing_oracle.mjs +389 -0
- package/dist/lib/evg/original/EVGColor.clj +310 -0
- package/dist/lib/evg/original/EVGColorContext.rgr +178 -0
- package/dist/lib/evg/original/SVGPath.rgr +627 -0
- package/dist/lib/evg/original/Vec2.crgr +103 -0
- package/dist/lib/evg/ranger.json +9 -0
- package/dist/lib/evg/showcase/README.md +246 -0
- package/dist/lib/evg/showcase/assets/emblem.svg +30 -0
- package/dist/lib/evg/showcase/assets/rosette.svg +22 -0
- package/dist/lib/evg/showcase/build.mjs +651 -0
- package/dist/lib/evg/showcase/pages/album.tsx +30 -0
- package/dist/lib/evg/showcase/pages/boxmodel.tsx +37 -0
- package/dist/lib/evg/showcase/pages/cards.tsx +41 -0
- package/dist/lib/evg/showcase/pages/chart_api.tsx +170 -0
- package/dist/lib/evg/showcase/pages/charts.tsx +219 -0
- package/dist/lib/evg/showcase/pages/drawing.tsx +160 -0
- package/dist/lib/evg/showcase/pages/emoji.tsx +91 -0
- package/dist/lib/evg/showcase/pages/flex.tsx +46 -0
- package/dist/lib/evg/showcase/pages/more.tsx +332 -0
- package/dist/lib/evg/showcase/pages/plots.tsx +262 -0
- package/dist/lib/evg/showcase/pages/svg.tsx +63 -0
- package/dist/lib/evg/showcase/pages/tables.tsx +209 -0
- package/dist/lib/evg/showcase/pages/typography.tsx +43 -0
- package/dist/lib/evg/showcase/pages/units.tsx +35 -0
- package/dist/lib/evg/showcase/pages/variants.tsx +233 -0
- package/dist/lib/evg/showcase/pages/vector.tsx +75 -0
- package/dist/lib/evg/showcase/pages/views.tsx +223 -0
- package/dist/lib/evg/showcase/tests/chart_api_smoke.mjs +339 -0
- package/dist/lib/evg/showcase/tests/gl_smoke.mjs +125 -0
- package/dist/lib/evg/showcase/themes/chart_api-default.css +15 -0
- package/dist/lib/evg/showcase/themes/charts-default.css +29 -0
- package/dist/lib/evg/showcase/themes/drawing-default.css +35 -0
- package/dist/lib/evg/showcase/themes/more-default.css +128 -0
- package/dist/lib/evg/showcase/themes/plots-default.css +18 -0
- package/dist/lib/evg/showcase/themes/showcase.css +508 -0
- package/dist/lib/evg/showcase/themes/tables-default.css +123 -0
- package/dist/lib/evg/showcase/themes/variants-default.css +15 -0
- package/dist/lib/evg/showcase/themes/views-default.css +15 -0
- package/dist/lib/evg/tools/bench_vs_potrace.mjs +290 -0
- package/dist/lib/evg/tools/evg_image_tool.rgr +488 -0
- package/dist/lib/evg/tools/evg_trace_bench.rgr +114 -0
- package/dist/lib/evg/tools/evg_trace_cli.rgr +662 -0
- package/dist/lib/evg/tools/evg_trace_cpp_bench.rgr +83 -0
- package/dist/lib/evg/tools/run_trace_bench.sh +74 -0
- package/dist/lib/evg/tools/run_trace_cli_smoke.sh +128 -0
- package/dist/lib/evg/web/responsive/EvgResponsiveCheck.rgr +271 -0
- package/dist/lib/evg/web/responsive/EvgResponsiveDemo.rgr +531 -0
- package/dist/lib/evg/web/responsive/README.md +97 -0
- package/dist/lib/evg/web/responsive/build.mjs +90 -0
- package/dist/lib/evg/web/responsive/dom-check.mjs +169 -0
- package/dist/lib/evg/web/responsive/index.html +177 -0
- package/dist/lib/evg/web/responsive/smoke.mjs +221 -0
- package/dist/lib/evg/web/tools/assets-client.mjs +95 -0
- package/dist/lib/evg/web/tools/boot-bench.mjs +189 -0
- package/dist/lib/evg/web/tools/inline-assets.mjs +119 -0
- package/dist/lib/evg/web/tools/minify.mjs +60 -0
- package/dist/lib/evg/web/tracer/build.mjs +87 -0
- package/dist/lib/evg/web/tracer/index.html +2805 -0
- package/dist/lib/evg/web/tracer/sample.png +0 -0
- package/dist/lib/evg/web/tracer/smoke.mjs +1162 -0
- package/dist/lib/evgr/Cargo.lock +21 -0
- package/dist/lib/evgr/Cargo.toml +19 -0
- package/dist/lib/evgr/README.md +140 -0
- package/dist/lib/evgr/bench/NativeBench.rgr +246 -0
- package/dist/lib/evgr/bench/compare.mjs +252 -0
- package/dist/lib/evgr/bench/speed.mjs +277 -0
- package/dist/lib/evgr/bin/.gitignore +3 -0
- package/dist/lib/evgr/src/bin/bench.rs +106 -0
- package/dist/lib/evgr/src/bin/smoke.rs +13 -0
- package/dist/lib/evgr/src/grid.rs +730 -0
- package/dist/lib/evgr/src/lib.rs +1003 -0
- package/dist/lib/evgr/src/style.rs +468 -0
- package/dist/lib/evgr/src/text.rs +83 -0
- package/dist/lib/image/BitReader.rgr +171 -0
- package/dist/lib/image/Buffer.rgr +173 -0
- package/dist/lib/image/DCT.rgr +283 -0
- package/dist/lib/image/Deflate.rgr +339 -0
- package/dist/lib/image/HuffmanDecoder.rgr +181 -0
- package/dist/lib/image/ImageBuffer.rgr +706 -0
- package/dist/lib/image/JPEGDecoder.rgr +808 -0
- package/dist/lib/image/PNGDecoder.rgr +544 -0
- package/dist/lib/image/PNGEncoder.rgr +388 -0
- package/dist/lib/image/PPMImage.rgr +224 -0
- package/dist/lib/image/ProgressiveJPEGDecoder.rgr +1154 -0
- package/dist/lib/image/README.md +33 -0
- package/dist/lib/image/RasterBuffer.rgr +294 -0
- package/dist/lib/image/VP8BoolDecoder.rgr +163 -0
- package/dist/lib/image/WebPDecoder.rgr +433 -0
- package/dist/lib/image/WebPLossless.rgr +1035 -0
- package/dist/lib/image/WebPLossy.rgr +1929 -0
- package/dist/lib/image/ranger.json +9 -0
- package/dist/lib/image/testdata/webp/anim_2f_24x16.webp +0 -0
- package/dist/lib/image/testdata/webp/fixtures.txt +33 -0
- package/dist/lib/image/testdata/webp/gen_fixtures.py +261 -0
- package/dist/lib/image/testdata/webp/ll_1x1.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_alpha_29x21.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_gradient_64x64.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_meta_32x32.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_noise_17x9.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal11_23x11.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal2_19x7.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal40_16x16.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_pal4_13x5.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_photo_40x30.webp +0 -0
- package/dist/lib/image/testdata/webp/ll_predictors_64x32.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_1x1.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f0_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f1_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f2_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_raw_f3_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f0_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f1_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f2_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alph_vp8l_f3_21x13.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_alpha_33x17.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_exif_15x11.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_i16_96x80.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_nofilter_24x20.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_odd_17x9.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_photo_48x40.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_q100_20x18.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_sharp_40x36.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_simple_filter_33x31.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_vpx_parts8_37x45.webp +0 -0
- package/dist/lib/image/testdata/webp/ly_vpx_skip_96x80.webp +0 -0
- package/dist/lib/image/tests/WebPDecodeTool.rgr +81 -0
- package/dist/lib/image/tests/WebPDecoderTest.rgr +1162 -0
- package/dist/lib/image/tests/run_webp_tests.sh +39 -0
- package/dist/lib/rust/RsJson.rgr +468 -0
- package/dist/lib/rust/RsPrelude.rgr +1663 -0
- package/dist/lib/shell_test.rgr +7 -7
- package/dist/lib/stdlib.rgr +21 -5
- package/dist/lib/zip/ranger.json +6 -0
- package/dist/rgrc.js +87318 -67610
- package/package.json +1010 -1040
- package/dist/README.md +0 -117
- package/dist/package.json +0 -47
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EVGStyleVarTest — the palette, and where it is allowed to live
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
;
|
|
7
|
+
; `@vars { --ink: #09090b }` and `color: var(--ink)`. Two claims are worth
|
|
8
|
+
; testing and one of them is not about colour at all:
|
|
9
|
+
;
|
|
10
|
+
; WHAT IT MEANS. A theme replaces a palette rather than ninety rules, a
|
|
11
|
+
; fallback stands in for a name nobody defined, and a name
|
|
12
|
+
; nobody defined and no fallback is an ERROR — the
|
|
13
|
+
; declaration is dropped rather than written half resolved,
|
|
14
|
+
; because half a shorthand is worse than the value that was
|
|
15
|
+
; there before.
|
|
16
|
+
;
|
|
17
|
+
; WHAT IT COSTS. `var()` is resolved when a PLAN is built, so two elements
|
|
18
|
+
; of the same class resolve once between them. That is the
|
|
19
|
+
; whole performance claim of the feature and it is checked
|
|
20
|
+
; here against the sheet's own counters, not asserted in a
|
|
21
|
+
; comment.
|
|
22
|
+
;
|
|
23
|
+
; And the honesty rule the syntax exists for: this engine has no root element
|
|
24
|
+
; and no inheritance, so a palette written on a class would look element-scoped
|
|
25
|
+
; and not be. `--x` in a class rule is reported, not quietly ignored.
|
|
26
|
+
; ==============================================================================
|
|
27
|
+
|
|
28
|
+
Import "EVGElement.rgr"
|
|
29
|
+
Import "EVGUnit.rgr"
|
|
30
|
+
Import "EVGStyleSheet.rgr"
|
|
31
|
+
|
|
32
|
+
class VarCheck {
|
|
33
|
+
def passed:int 0
|
|
34
|
+
def failed:int 0
|
|
35
|
+
|
|
36
|
+
fn ok:void (name:string cond:boolean) {
|
|
37
|
+
if cond {
|
|
38
|
+
passed = (passed + 1)
|
|
39
|
+
print (" PASS " + name)
|
|
40
|
+
} {
|
|
41
|
+
failed = (failed + 1)
|
|
42
|
+
print (" FAIL " + name)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fn eqStr:void (name:string got:string want:string) {
|
|
47
|
+
def good:boolean (got == want)
|
|
48
|
+
if (good == false) {
|
|
49
|
+
print (((" got '" + got) + "' want '") + want + "'")
|
|
50
|
+
}
|
|
51
|
+
this.ok(name good)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fn eqInt:void (name:string got:int want:int) {
|
|
55
|
+
def good:boolean (got == want)
|
|
56
|
+
if (good == false) {
|
|
57
|
+
print ((" got " + (to_string got)) + " want " + (to_string want))
|
|
58
|
+
}
|
|
59
|
+
this.ok(name good)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class EVGStyleVarTest {
|
|
64
|
+
|
|
65
|
+
sfn sheetOf:EVGStyleSheet (css:string) {
|
|
66
|
+
def s (new EVGStyleSheet())
|
|
67
|
+
s.parse(css)
|
|
68
|
+
s.setViewport(800.0 600.0 false)
|
|
69
|
+
return s
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
sfn boxWith:EVGElement (cls:string) {
|
|
73
|
+
def el (EVGElement.createDiv())
|
|
74
|
+
el.id = "box"
|
|
75
|
+
el.className = cls
|
|
76
|
+
return el
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
; The background's red channel, or -1 when nothing was written. A number
|
|
80
|
+
; the failure can print, rather than "not equal".
|
|
81
|
+
;
|
|
82
|
+
; `isSet`, and not whether the field is there: a fresh element carries
|
|
83
|
+
; `EVGColor.noColor()`, whose red is 0 — so "nothing was written" and
|
|
84
|
+
; "black was written" look identical to anything that reads the channel.
|
|
85
|
+
sfn bgRed:int (el:EVGElement) {
|
|
86
|
+
if el.backgroundColor {
|
|
87
|
+
def c:EVGColor (unwrap el.backgroundColor)
|
|
88
|
+
if (c.isSet == false) {
|
|
89
|
+
return (0 - 1)
|
|
90
|
+
}
|
|
91
|
+
return (c.red())
|
|
92
|
+
}
|
|
93
|
+
return (0 - 1)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
sfn inkRed:int (el:EVGElement) {
|
|
97
|
+
if el.color {
|
|
98
|
+
def c:EVGColor (unwrap el.color)
|
|
99
|
+
if (c.isSet == false) {
|
|
100
|
+
return (0 - 1)
|
|
101
|
+
}
|
|
102
|
+
return (c.red())
|
|
103
|
+
}
|
|
104
|
+
return (0 - 1)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
; The BOX's border colour, which is where the `border` shorthand puts it —
|
|
108
|
+
; the element has a field of the same name and the shorthand does not write
|
|
109
|
+
; to it.
|
|
110
|
+
sfn borderRed:int (el:EVGElement) {
|
|
111
|
+
if el.box.borderColor {
|
|
112
|
+
def c:EVGColor (unwrap el.box.borderColor)
|
|
113
|
+
if (c.isSet == false) {
|
|
114
|
+
return (0 - 1)
|
|
115
|
+
}
|
|
116
|
+
return (c.red())
|
|
117
|
+
}
|
|
118
|
+
return (0 - 1)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
; --- what it means --------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
sfn testSubstitution:void (c:VarCheck) {
|
|
124
|
+
print "--- a value can name the palette ---"
|
|
125
|
+
def css:string ("@vars { --ink: rgb(20,0,0); }"
|
|
126
|
+
+ " .box { color: var(--ink); }")
|
|
127
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
128
|
+
c.eqInt("the palette was read" (s.getVarCount()) 1)
|
|
129
|
+
c.eqInt("and it is not a rule" (s.getRuleCount()) 1)
|
|
130
|
+
c.eqInt("nothing was rejected" (s.getErrorCount()) 0)
|
|
131
|
+
|
|
132
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
133
|
+
s.applyTree(el "")
|
|
134
|
+
c.eqInt("the element got the palette's value" (EVGStyleVarTest.inkRed(el)) 20)
|
|
135
|
+
|
|
136
|
+
; And the palette does not have to be written first. Nothing is
|
|
137
|
+
; resolved while the sheet is being read — the whole file is parsed,
|
|
138
|
+
; and a value is resolved when a plan for it is built.
|
|
139
|
+
def later:EVGStyleSheet (EVGStyleVarTest.sheetOf(".box { color: var(--ink); } @vars { --ink: rgb(21,0,0); }"))
|
|
140
|
+
def el2:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
141
|
+
later.applyTree(el2 "")
|
|
142
|
+
c.eqInt("declared after it is used" (EVGStyleVarTest.inkRed(el2)) 21)
|
|
143
|
+
c.eqInt("and still no error" (later.getErrorCount()) 0)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
sfn testShorthand:void (c:VarCheck) {
|
|
147
|
+
print "--- and it works inside a shorthand ---"
|
|
148
|
+
; The point of substituting TEXT before the value reaches
|
|
149
|
+
; `setAttribute`: no property has to know that variables exist, so this
|
|
150
|
+
; reaches the border shorthand's colour with nothing added for it.
|
|
151
|
+
def css:string ("@vars { --line: rgb(90,0,0); }"
|
|
152
|
+
+ " .box { border: 2px solid var(--line); }")
|
|
153
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
154
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
155
|
+
s.applyTree(el "")
|
|
156
|
+
c.eqInt("no error" (s.getErrorCount()) 0)
|
|
157
|
+
c.eqInt("the shorthand's colour came from the palette" (EVGStyleVarTest.borderRed(el)) 90)
|
|
158
|
+
el.box.resolveUnits(400.0 200.0 16.0 16.0 0.0 0.0)
|
|
159
|
+
c.eqInt("and the rest of the shorthand survived" (to_int el.box.borderWidthPx) 2)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
sfn testTheme:void (c:VarCheck) {
|
|
163
|
+
print "--- a theme is a palette, not a second set of rules ---"
|
|
164
|
+
def css:string ("@vars { --paper: rgb(10,0,0); }"
|
|
165
|
+
+ " @vars marine { --paper: rgb(200,0,0); }"
|
|
166
|
+
+ " .box { background-color: var(--paper); }")
|
|
167
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
168
|
+
c.eqInt("one rule, two declarations of one name" (s.getRuleCount()) 1)
|
|
169
|
+
c.eqInt("both are in the palette" (s.getVarCount()) 2)
|
|
170
|
+
|
|
171
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
172
|
+
s.applyTree(el "")
|
|
173
|
+
c.eqInt("with no theme the unscoped value" (EVGStyleVarTest.bgRed(el)) 10)
|
|
174
|
+
s.applyTree(el "marine")
|
|
175
|
+
c.eqInt("under the theme the scoped one" (EVGStyleVarTest.bgRed(el)) 200)
|
|
176
|
+
; The thing a theme built out of rules has to be careful about — a
|
|
177
|
+
; property with no unscoped counterpart stays behind — cannot happen
|
|
178
|
+
; here: there is one declaration and it is resolved per theme.
|
|
179
|
+
s.applyTree(el "")
|
|
180
|
+
c.eqInt("and leaving it puts the first back" (EVGStyleVarTest.bgRed(el)) 10)
|
|
181
|
+
; A theme nobody wrote a palette for is not an error: it falls through
|
|
182
|
+
; to the unscoped values, which is what "optional theming" means.
|
|
183
|
+
s.applyTree(el "sunset")
|
|
184
|
+
c.eqInt("an unknown theme is just the unscoped palette" (EVGStyleVarTest.bgRed(el)) 10)
|
|
185
|
+
c.eqInt("and says nothing" (s.getErrorCount()) 0)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
sfn testThemeList:void (c:VarCheck) {
|
|
189
|
+
print "--- more than one theme can be on at once ---"
|
|
190
|
+
; The case an app hits the moment it has both: some rules scoped to a
|
|
191
|
+
; PLACE — a screen, a print size — and its colours to a PALETTE. With
|
|
192
|
+
; one slot the two fight over it.
|
|
193
|
+
def css:string ("@vars { --paper: rgb(10,0,0); }"
|
|
194
|
+
+ " @vars ocean { --paper: rgb(30,0,0); }"
|
|
195
|
+
+ " .box { background-color: var(--paper); }"
|
|
196
|
+
+ " .theme-session .box { color: rgb(1,0,0); }")
|
|
197
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
198
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
199
|
+
|
|
200
|
+
s.applyTree(el "session")
|
|
201
|
+
c.eqInt("the screen's rule applies" (EVGStyleVarTest.inkRed(el)) 1)
|
|
202
|
+
c.eqInt("and the palette is the unscoped one" (EVGStyleVarTest.bgRed(el)) 10)
|
|
203
|
+
|
|
204
|
+
; Both names, and both hold.
|
|
205
|
+
s.applyTree(el "session ocean")
|
|
206
|
+
c.eqInt("the screen's rule still applies" (EVGStyleVarTest.inkRed(el)) 1)
|
|
207
|
+
c.eqInt("and now so does the palette" (EVGStyleVarTest.bgRed(el)) 30)
|
|
208
|
+
|
|
209
|
+
; Order in the list buys nothing, and a name nobody wrote is not an
|
|
210
|
+
; error — the same as a single unknown theme.
|
|
211
|
+
s.applyTree(el "ocean session")
|
|
212
|
+
c.eqInt("the order of the list does not matter" (EVGStyleVarTest.bgRed(el)) 30)
|
|
213
|
+
s.applyTree(el "ocean sunset")
|
|
214
|
+
c.eqInt("an unknown name in the list is ignored" (EVGStyleVarTest.bgRed(el)) 30)
|
|
215
|
+
c.eqInt("and says nothing" (s.getErrorCount()) 0)
|
|
216
|
+
|
|
217
|
+
; A prefix is not a name: "ocean" must not be found inside "oceanic".
|
|
218
|
+
s.applyTree(el "oceanic")
|
|
219
|
+
c.eqInt("a name is a whole token" (EVGStyleVarTest.bgRed(el)) 10)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
sfn testIndirection:void (c:VarCheck) {
|
|
223
|
+
print "--- a variable may be written in terms of another ---"
|
|
224
|
+
def css:string ("@vars { --brand: rgb(70,0,0); --button: var(--brand); }"
|
|
225
|
+
+ " .box { background-color: var(--button); }")
|
|
226
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
227
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
228
|
+
s.applyTree(el "")
|
|
229
|
+
c.eqInt("resolved through the chain" (EVGStyleVarTest.bgRed(el)) 70)
|
|
230
|
+
c.eqInt("no error" (s.getErrorCount()) 0)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
sfn testThemeIndirection:void (c:VarCheck) {
|
|
234
|
+
print "--- and a theme may re-point one name and move everything under it ---"
|
|
235
|
+
; What a palette is FOR: "marine" says one thing about the brand and
|
|
236
|
+
; the button follows, because the button was never a colour.
|
|
237
|
+
def css:string ("@vars { --brand: rgb(70,0,0); --button: var(--brand); }"
|
|
238
|
+
+ " @vars marine { --brand: rgb(180,0,0); }"
|
|
239
|
+
+ " .box { background-color: var(--button); }")
|
|
240
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
241
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
242
|
+
s.applyTree(el "marine")
|
|
243
|
+
c.eqInt("the theme reached through the indirection" (EVGStyleVarTest.bgRed(el)) 180)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
sfn testFallback:void (c:VarCheck) {
|
|
247
|
+
print "--- a fallback stands in, and steps aside ---"
|
|
248
|
+
def css:string ("@vars { --known: rgb(30,0,0); }"
|
|
249
|
+
+ " .a { color: var(--known, rgb(240,0,0)); }"
|
|
250
|
+
+ " .b { color: var(--missing, rgb(240,0,0)); }"
|
|
251
|
+
+ " .c { color: var(--missing, rgb(0,0,0)); background-color: var(--nope, rgb(120,0,0)); }")
|
|
252
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
253
|
+
def a:EVGElement (EVGStyleVarTest.boxWith("a"))
|
|
254
|
+
s.applyTree(a "")
|
|
255
|
+
c.eqInt("a defined name ignores the fallback" (EVGStyleVarTest.inkRed(a)) 30)
|
|
256
|
+
def b:EVGElement (EVGStyleVarTest.boxWith("b"))
|
|
257
|
+
s.applyTree(b "")
|
|
258
|
+
c.eqInt("an undefined one takes it" (EVGStyleVarTest.inkRed(b)) 240)
|
|
259
|
+
def d:EVGElement (EVGStyleVarTest.boxWith("c"))
|
|
260
|
+
s.applyTree(d "")
|
|
261
|
+
c.eqInt("and a fallback may be a function call" (EVGStyleVarTest.bgRed(d)) 120)
|
|
262
|
+
c.eqInt("none of which is an error" (s.getErrorCount()) 0)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
; --- what it refuses to guess at ------------------------------------------
|
|
266
|
+
|
|
267
|
+
sfn testUndefined:void (c:VarCheck) {
|
|
268
|
+
print "--- an undefined name with no fallback is reported, not painted ---"
|
|
269
|
+
def css:string (".box { background-color: rgb(5,0,0); }"
|
|
270
|
+
+ " .box { background-color: var(--nobody); }")
|
|
271
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
272
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
273
|
+
s.applyTree(el "")
|
|
274
|
+
c.eqInt("the sheet says so" (s.getErrorCount()) 1)
|
|
275
|
+
; The declaration is DROPPED, so what shows is the rule before it and
|
|
276
|
+
; not an unparseable colour. A page with a typo in it keeps working and
|
|
277
|
+
; the error list says where.
|
|
278
|
+
c.eqInt("and the value before it stands" (EVGStyleVarTest.bgRed(el)) 5)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
sfn testReportedOnce:void (c:VarCheck) {
|
|
282
|
+
print "--- and reported once, however many classes use it ---"
|
|
283
|
+
; Parsing happens once; resolution happens wherever a plan is built. So
|
|
284
|
+
; one typo used by six classes would be six copies of one sentence in
|
|
285
|
+
; the panel that exists to say which sentence it is.
|
|
286
|
+
def css:string (".a { color: var(--nobody); }"
|
|
287
|
+
+ " .b { color: var(--nobody); }"
|
|
288
|
+
+ " .c { color: var(--nobody); }")
|
|
289
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
290
|
+
def root:EVGElement (EVGStyleVarTest.boxWith("wrap"))
|
|
291
|
+
root.addChild((EVGStyleVarTest.boxWith("a")))
|
|
292
|
+
root.addChild((EVGStyleVarTest.boxWith("b")))
|
|
293
|
+
root.addChild((EVGStyleVarTest.boxWith("c")))
|
|
294
|
+
s.applyTree(root "")
|
|
295
|
+
c.eqInt("three plans, one sentence" (s.getErrorCount()) 1)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
sfn testCustomPropertyOnAClass:void (c:VarCheck) {
|
|
299
|
+
print "--- and a palette written on a class is refused ---"
|
|
300
|
+
; There is no inheritance here, so this would look element-scoped and
|
|
301
|
+
; not be: `.box` would be the only place the name existed, and it
|
|
302
|
+
; would reach nothing. `@vars` is the only place it means something.
|
|
303
|
+
def css:string ".box { --ink: rgb(10,0,0); color: rgb(60,0,0); }"
|
|
304
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
305
|
+
c.eqInt("it is reported" (s.getErrorCount()) 1)
|
|
306
|
+
c.eqInt("and it did not join the palette" (s.getVarCount()) 0)
|
|
307
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
308
|
+
s.applyTree(el "")
|
|
309
|
+
c.eqInt("the rest of the rule is untouched" (EVGStyleVarTest.inkRed(el)) 60)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
sfn testMalformed:void (c:VarCheck) {
|
|
313
|
+
print "--- malformed palettes and malformed uses ---"
|
|
314
|
+
def s1:EVGStyleSheet (EVGStyleVarTest.sheetOf("@vars theme marine { --a: rgb(1,0,0); }"))
|
|
315
|
+
c.eqInt("@vars takes at most a theme name" (s1.getErrorCount()) 1)
|
|
316
|
+
c.eqInt("and stores nothing from a header it did not understand" (s1.getVarCount()) 0)
|
|
317
|
+
|
|
318
|
+
def s2:EVGStyleSheet (EVGStyleVarTest.sheetOf("@vars { color: rgb(1,0,0); }"))
|
|
319
|
+
c.eqInt("a property inside @vars is reported" (s2.getErrorCount()) 1)
|
|
320
|
+
|
|
321
|
+
; What follows asserts that NOTHING was written, which is the half of
|
|
322
|
+
; "reported rather than painted" that matters — see `bgRed` for why
|
|
323
|
+
; that is a question about `isSet` and not about a colour channel.
|
|
324
|
+
def s3:EVGStyleSheet (EVGStyleVarTest.sheetOf("@vars { --a: rgb(9,0,0); } .box { background-color: var(--a; }"))
|
|
325
|
+
def el3:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
326
|
+
s3.applyTree(el3 "")
|
|
327
|
+
c.eqInt("an unclosed var() is reported" (s3.getErrorCount()) 1)
|
|
328
|
+
c.eqInt("and writes nothing" (EVGStyleVarTest.bgRed(el3)) (0 - 1))
|
|
329
|
+
|
|
330
|
+
; `--a: var(--b)` and `--b: var(--a)`. The check that matters is that
|
|
331
|
+
; this RETURNS.
|
|
332
|
+
def s4:EVGStyleSheet (EVGStyleVarTest.sheetOf("@vars { --a: var(--b); --b: var(--a); } .box { background-color: var(--a); }"))
|
|
333
|
+
def el4:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
334
|
+
s4.applyTree(el4 "")
|
|
335
|
+
c.ok("a cycle is reported rather than spun on" ((s4.getErrorCount()) > 0))
|
|
336
|
+
c.eqInt("and writes nothing" (EVGStyleVarTest.bgRed(el4)) (0 - 1))
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
; --- what it costs --------------------------------------------------------
|
|
340
|
+
|
|
341
|
+
sfn testResolvedPerPlanNotPerElement:void (c:VarCheck) {
|
|
342
|
+
print "--- resolved once per plan, not once per element ---"
|
|
343
|
+
def css:string ("@vars { --ink: rgb(40,0,0); }"
|
|
344
|
+
+ " .box { color: var(--ink); background-color: var(--ink); }")
|
|
345
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
346
|
+
def parent:EVGElement (EVGStyleVarTest.boxWith("wrap"))
|
|
347
|
+
def i:int 0
|
|
348
|
+
while (i < 50) {
|
|
349
|
+
parent.addChild((EVGStyleVarTest.boxWith("box")))
|
|
350
|
+
i = (i + 1)
|
|
351
|
+
}
|
|
352
|
+
s.applyTree(parent "")
|
|
353
|
+
; Fifty-one elements, two distinct class strings, and the sheet built
|
|
354
|
+
; a plan for each: every other element replayed one. The palette was
|
|
355
|
+
; therefore consulted twice — once for each declaration of `.box` —
|
|
356
|
+
; however many rows the page has.
|
|
357
|
+
c.eqInt("one plan per distinct class" s.planMisses 2)
|
|
358
|
+
c.eqInt("everything else replayed one" s.planHits 49)
|
|
359
|
+
def kid:EVGElement (parent.getChild(7))
|
|
360
|
+
c.eqInt("and they all got the value" (EVGStyleVarTest.inkRed(kid)) 40)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
; --- the palette answers the viewport too ---------------------------------
|
|
364
|
+
|
|
365
|
+
sfn testMediaScoped:void (c:VarCheck) {
|
|
366
|
+
print "--- a variable may answer a media query ---"
|
|
367
|
+
def css:string ("@vars { --pad: 20px; }"
|
|
368
|
+
+ " @media (max-width: 640px) { @vars { --pad: 4px; } }"
|
|
369
|
+
+ " .box { padding: var(--pad); }")
|
|
370
|
+
def s (new EVGStyleSheet())
|
|
371
|
+
s.parse(css)
|
|
372
|
+
s.setViewport(1000.0 800.0 false)
|
|
373
|
+
def wide:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
374
|
+
s.applyTree(wide "")
|
|
375
|
+
wide.box.resolveUnits(400.0 200.0 16.0 16.0 0.0 0.0)
|
|
376
|
+
c.eqInt("on a wide surface the unconditional value" (to_int wide.box.paddingTopPx) 20)
|
|
377
|
+
; And the narrow one is not a second element: the same sheet, told the
|
|
378
|
+
; surface changed. `setViewport` drops the plans, so the palette is
|
|
379
|
+
; consulted again rather than the old answer being replayed.
|
|
380
|
+
s.setViewport(500.0 800.0 false)
|
|
381
|
+
def narrow:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
382
|
+
s.applyTree(narrow "")
|
|
383
|
+
narrow.box.resolveUnits(400.0 200.0 16.0 16.0 0.0 0.0)
|
|
384
|
+
c.eqInt("on a narrow one the conditional value" (to_int narrow.box.paddingTopPx) 4)
|
|
385
|
+
c.eqInt("no error either way" (s.getErrorCount()) 0)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
; --- reloading -------------------------------------------------------------
|
|
389
|
+
|
|
390
|
+
sfn testReload:void (c:VarCheck) {
|
|
391
|
+
print "--- reloading replaces the palette rather than adding to it ---"
|
|
392
|
+
def s (new EVGStyleSheet())
|
|
393
|
+
s.parse("@vars { --ink: rgb(11,0,0); } .box { color: var(--ink); }")
|
|
394
|
+
s.setViewport(800.0 600.0 false)
|
|
395
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
396
|
+
s.applyTree(el "")
|
|
397
|
+
c.eqInt("the first sheet" (EVGStyleVarTest.inkRed(el)) 11)
|
|
398
|
+
; The failure this guards: `parse` APPENDS, and the later of two equal
|
|
399
|
+
; declarations wins — so a palette that is not cleared means the OLD
|
|
400
|
+
; value outlives the edit. Which is exactly the case the inspector's
|
|
401
|
+
; live editing walks into.
|
|
402
|
+
s.reload("@vars { --ink: rgb(222,0,0); } .box { color: var(--ink); }")
|
|
403
|
+
c.eqInt("and only one name after the reload" (s.getVarCount()) 1)
|
|
404
|
+
s.applyTree(el "")
|
|
405
|
+
c.eqInt("the edited value shows" (EVGStyleVarTest.inkRed(el)) 222)
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
sfn testTransitionThroughAVariable:void (c:VarCheck) {
|
|
409
|
+
print "--- a transition may be built out of the palette ---"
|
|
410
|
+
; `transition` is checked for a timing function nobody implements, and
|
|
411
|
+
; that check runs when the sheet is parsed — where `var(--speed)` reads
|
|
412
|
+
; as a function call and would be reported as an unsupported one. The
|
|
413
|
+
; check has to wait for the value.
|
|
414
|
+
def css:string ("@vars { --speed: 150ms; }"
|
|
415
|
+
+ " .box { transition: background-color var(--speed) ease; background-color: rgb(1,0,0); }")
|
|
416
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
417
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
418
|
+
s.applyTree(el "")
|
|
419
|
+
c.eqInt("the variable is not mistaken for a timing function" (s.getErrorCount()) 0)
|
|
420
|
+
c.eqStr("and the resolved transition reached the element" el.transitionSpec
|
|
421
|
+
"background-color 150ms ease")
|
|
422
|
+
|
|
423
|
+
; And a timing function that really is unsupported is still reported,
|
|
424
|
+
; now that the check happens later: `spring()` is CSS-shaped and is not
|
|
425
|
+
; CSS.
|
|
426
|
+
def bad:EVGStyleSheet (EVGStyleVarTest.sheetOf("@vars { --e: spring(1, 2); } .box { transition: opacity 100ms var(--e); }"))
|
|
427
|
+
def el2:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
428
|
+
bad.applyTree(el2 "")
|
|
429
|
+
c.eqInt("an unsupported one still is" (bad.getErrorCount()) 1)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
sfn testNoVariables:void (c:VarCheck) {
|
|
433
|
+
print "--- a sheet with no variables in it is untouched ---"
|
|
434
|
+
def css:string ".box { color: rgb(3,0,0); background-color: rgb(4,0,0); }"
|
|
435
|
+
def s:EVGStyleSheet (EVGStyleVarTest.sheetOf(css))
|
|
436
|
+
def el:EVGElement (EVGStyleVarTest.boxWith("box"))
|
|
437
|
+
s.applyTree(el "")
|
|
438
|
+
c.eqInt("no palette" (s.getVarCount()) 0)
|
|
439
|
+
c.eqInt("no errors" (s.getErrorCount()) 0)
|
|
440
|
+
c.eqInt("and the values it always had" (EVGStyleVarTest.inkRed(el)) 3)
|
|
441
|
+
c.eqInt("both of them" (EVGStyleVarTest.bgRed(el)) 4)
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
sfn main:void () {
|
|
445
|
+
def c (new VarCheck())
|
|
446
|
+
print "=== EVG stylesheet: custom properties ==="
|
|
447
|
+
EVGStyleVarTest.testSubstitution(c)
|
|
448
|
+
EVGStyleVarTest.testShorthand(c)
|
|
449
|
+
EVGStyleVarTest.testTheme(c)
|
|
450
|
+
EVGStyleVarTest.testThemeList(c)
|
|
451
|
+
EVGStyleVarTest.testIndirection(c)
|
|
452
|
+
EVGStyleVarTest.testThemeIndirection(c)
|
|
453
|
+
EVGStyleVarTest.testFallback(c)
|
|
454
|
+
EVGStyleVarTest.testUndefined(c)
|
|
455
|
+
EVGStyleVarTest.testReportedOnce(c)
|
|
456
|
+
EVGStyleVarTest.testCustomPropertyOnAClass(c)
|
|
457
|
+
EVGStyleVarTest.testMalformed(c)
|
|
458
|
+
EVGStyleVarTest.testResolvedPerPlanNotPerElement(c)
|
|
459
|
+
EVGStyleVarTest.testMediaScoped(c)
|
|
460
|
+
EVGStyleVarTest.testTransitionThroughAVariable(c)
|
|
461
|
+
EVGStyleVarTest.testReload(c)
|
|
462
|
+
EVGStyleVarTest.testNoVariables(c)
|
|
463
|
+
print ""
|
|
464
|
+
print (("passed=" + (to_string c.passed)) + " failed=" + (to_string c.failed))
|
|
465
|
+
if (c.failed > 0) {
|
|
466
|
+
print "FAILURES"
|
|
467
|
+
} {
|
|
468
|
+
print "ALL PASS"
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; EVGText.rgr - Text element for EVG layout
|
|
4
|
+
|
|
5
|
+
Import "EVGElement.rgr"
|
|
6
|
+
Import "EVGTextMeasurer.rgr"
|
|
7
|
+
|
|
8
|
+
class EVGText {
|
|
9
|
+
; Extend base element
|
|
10
|
+
def element@(optional):EVGElement
|
|
11
|
+
|
|
12
|
+
; Text content
|
|
13
|
+
def text:string ""
|
|
14
|
+
|
|
15
|
+
; Calculated text metrics
|
|
16
|
+
def measuredWidth:double 0.0
|
|
17
|
+
def measuredHeight:double 0.0
|
|
18
|
+
def lineCount:int 1
|
|
19
|
+
def lines:[string]
|
|
20
|
+
|
|
21
|
+
Constructor () {
|
|
22
|
+
def el (new EVGElement())
|
|
23
|
+
el.tagName = "span"
|
|
24
|
+
el.elementType = 1
|
|
25
|
+
element = el
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
sfn create:EVGText (content:string) {
|
|
29
|
+
def t (new EVGText())
|
|
30
|
+
t.text = content
|
|
31
|
+
return t
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn getElement:EVGElement () {
|
|
35
|
+
return (unwrap element)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fn setText:void (content:string) {
|
|
39
|
+
text = content
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fn setFontSize:void (size:double) {
|
|
43
|
+
element.fontSize = (EVGUnit.px(size))
|
|
44
|
+
element.inheritedFontSize = size
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fn setFontFamily:void (family:string) {
|
|
48
|
+
element.fontFamily = family
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fn setColor:void (c:EVGColor) {
|
|
52
|
+
element.color = c
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
fn measureText:void (measurer:EVGTextMeasurer maxWidth:double) {
|
|
56
|
+
; Measure text and wrap if needed
|
|
57
|
+
def fs:double element.inheritedFontSize
|
|
58
|
+
def ff:string element.fontFamily
|
|
59
|
+
|
|
60
|
+
if (maxWidth > 0.0) {
|
|
61
|
+
; Wrap text to fit width
|
|
62
|
+
lines = (measurer.wrapText(text ff fs maxWidth))
|
|
63
|
+
lineCount = (array_length lines)
|
|
64
|
+
|
|
65
|
+
; Calculate total dimensions
|
|
66
|
+
def lineHeight:double (measurer.getLineHeight(ff fs))
|
|
67
|
+
measuredHeight = ((to_double lineCount) * lineHeight)
|
|
68
|
+
|
|
69
|
+
; Find widest line
|
|
70
|
+
measuredWidth = 0.0
|
|
71
|
+
def i:int 0
|
|
72
|
+
while (i < lineCount) {
|
|
73
|
+
def line:string (itemAt lines i)
|
|
74
|
+
def lineWidth:double (measurer.measureTextWidth(line ff fs))
|
|
75
|
+
if (lineWidth > measuredWidth) {
|
|
76
|
+
measuredWidth = lineWidth
|
|
77
|
+
}
|
|
78
|
+
i = i + 1
|
|
79
|
+
}
|
|
80
|
+
} {
|
|
81
|
+
; No wrapping - single line
|
|
82
|
+
def metrics:EVGTextMetrics (measurer.measureText(text ff fs))
|
|
83
|
+
measuredWidth = metrics.width
|
|
84
|
+
measuredHeight = metrics.height
|
|
85
|
+
lineCount = 1
|
|
86
|
+
clear lines
|
|
87
|
+
push lines text
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
; Update element calculated dimensions
|
|
91
|
+
element.calculatedWidth = measuredWidth
|
|
92
|
+
element.calculatedHeight = measuredHeight
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fn getLine:string (index:int) {
|
|
96
|
+
if (index < (array_length lines)) {
|
|
97
|
+
return (itemAt lines index)
|
|
98
|
+
}
|
|
99
|
+
return ""
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fn toString:string () {
|
|
103
|
+
return ("EVGText[\"" + text + "\" " + (to_string measuredWidth) + "x" + (to_string measuredHeight) + " lines:" + (to_string lineCount) + "]")
|
|
104
|
+
}
|
|
105
|
+
}
|