ranger-compiler 3.5.0 → 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 +1160 -19
- package/LICENSE +3 -1
- package/README.md +124 -29
- package/dist/Lang.rgr +1188 -290
- package/dist/api.d.ts +2343 -879
- package/dist/api.js +79924 -56922
- 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,208 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EVGHitTest — what is under the pointer, in the order things are painted
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
;
|
|
7
|
+
; A hit test that walks the tree answers with whatever the tree reaches first.
|
|
8
|
+
; That is the wrong answer the moment anything floats: a menu panel is drawn
|
|
9
|
+
; over the trigger beside it, and a click inside the panel has to reach the
|
|
10
|
+
; panel, not the trigger it happens to cover.
|
|
11
|
+
;
|
|
12
|
+
; So this does not walk the tree. It builds the SAME order the display list
|
|
13
|
+
; paints in — the normal tree, then the overlay surfaces in the order they were
|
|
14
|
+
; reached — and scans it backwards. Topmost wins because topmost is literally
|
|
15
|
+
; last, and there is one rule instead of two that can drift apart.
|
|
16
|
+
;
|
|
17
|
+
; Note what this is NOT. It answers "which element is under this point", i.e.
|
|
18
|
+
; the paint question. Where the resulting event then GOES is the tree's
|
|
19
|
+
; business: a click on a menu row is handled by the menu that owns the row, and
|
|
20
|
+
; ownership never moved, because an overlay surface never left the tree.
|
|
21
|
+
; ==============================================================================
|
|
22
|
+
|
|
23
|
+
Import "EVGElement.rgr"
|
|
24
|
+
|
|
25
|
+
class EVGHitTest {
|
|
26
|
+
; The paint order of the last call. A field rather than a return value
|
|
27
|
+
; threaded through the recursion: the walk defers surfaces as it meets them
|
|
28
|
+
; and comes back to them afterwards, which is exactly what `deferred` is.
|
|
29
|
+
def order:[EVGElement]
|
|
30
|
+
def deferred:[EVGElement]
|
|
31
|
+
|
|
32
|
+
Constructor () {
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
; Depth-first, minus the surfaces: those are put aside and painted after
|
|
36
|
+
; the whole normal tree.
|
|
37
|
+
fn collect:void (el:EVGElement) {
|
|
38
|
+
; `display: none` cannot be hit, nor anything under it.
|
|
39
|
+
if (el.isHidden()) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
el.settleShift()
|
|
43
|
+
push order el
|
|
44
|
+
def i:int 0
|
|
45
|
+
while (i < (array_length el.children)) {
|
|
46
|
+
def kid:EVGElement (itemAt el.children i)
|
|
47
|
+
if kid.isOverlay {
|
|
48
|
+
push deferred kid
|
|
49
|
+
} {
|
|
50
|
+
this.collect(kid)
|
|
51
|
+
}
|
|
52
|
+
i = (i + 1)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
; Back to front. A surface reached INSIDE a surface is appended while this
|
|
57
|
+
; loop is running, so a submenu lands after the menu that opened it — the
|
|
58
|
+
; stack falls out of the walk and nothing carries a z-index.
|
|
59
|
+
fn paintOrder:[EVGElement] (root:EVGElement) {
|
|
60
|
+
clear order
|
|
61
|
+
clear deferred
|
|
62
|
+
this.collect(root)
|
|
63
|
+
def i:int 0
|
|
64
|
+
while (i < (array_length deferred)) {
|
|
65
|
+
this.collect((itemAt deferred i))
|
|
66
|
+
i = (i + 1)
|
|
67
|
+
}
|
|
68
|
+
return order
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
sfn containsPoint:boolean (el:EVGElement px:double py:double) {
|
|
72
|
+
if (px < el.calculatedX) {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
if (py < el.calculatedY) {
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
if (px > (el.calculatedX + el.calculatedWidth)) {
|
|
79
|
+
return false
|
|
80
|
+
}
|
|
81
|
+
if (py > (el.calculatedY + el.calculatedHeight)) {
|
|
82
|
+
return false
|
|
83
|
+
}
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
; The same walk, minus what the point cannot see.
|
|
88
|
+
;
|
|
89
|
+
; A clipping box the point is OUTSIDE takes its whole subtree with it. That
|
|
90
|
+
; is not an optimisation: without it, a row scrolled out of a viewport is
|
|
91
|
+
; still sitting under the pointer at its unclipped position — invisible and
|
|
92
|
+
; clickable at once, which is the worst of the two. The paint order and the
|
|
93
|
+
; hit order have to agree about what is on the screen, and the display list
|
|
94
|
+
; stops drawing at exactly this boundary.
|
|
95
|
+
;
|
|
96
|
+
; The point is needed to do it, which is why this is a second walk rather
|
|
97
|
+
; than a rule inside `collect`: `paintOrder` answers "what is drawn, in
|
|
98
|
+
; order" and has no point to test against.
|
|
99
|
+
fn collectAt:void (el:EVGElement px:double py:double) {
|
|
100
|
+
if (el.clipsContent()) {
|
|
101
|
+
if ((EVGHitTest.containsPoint(el px py)) == false) {
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
; Nor can the point be in a subtree whose paint bounds — the union
|
|
106
|
+
; of every box beneath it, written by the layout and moved with it —
|
|
107
|
+
; do not hold it. This is the same test the display list culls with,
|
|
108
|
+
; and it is what keeps a pointer move over a long document from
|
|
109
|
+
; visiting every element in it: the rows are tested at their roots
|
|
110
|
+
; and the ones the point is not over are never entered. A subtree
|
|
111
|
+
; drawn somewhere its boxes do not say is never pruned.
|
|
112
|
+
if ((el.paintUnbounded == false) && ((el.isHidden()) == false)) {
|
|
113
|
+
if (px < el.paintLeft) { return }
|
|
114
|
+
if (py < el.paintTop) { return }
|
|
115
|
+
if (px > el.paintRight) { return }
|
|
116
|
+
if (py > el.paintBottom) { return }
|
|
117
|
+
}
|
|
118
|
+
el.settleShift()
|
|
119
|
+
push order el
|
|
120
|
+
def i:int 0
|
|
121
|
+
while (i < (array_length el.children)) {
|
|
122
|
+
def kid:EVGElement (itemAt el.children i)
|
|
123
|
+
if kid.isOverlay {
|
|
124
|
+
push deferred kid
|
|
125
|
+
} {
|
|
126
|
+
this.collectAt(kid px py)
|
|
127
|
+
}
|
|
128
|
+
i = (i + 1)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
; A surface is deferred here exactly as it is in `paintOrder`, so an
|
|
133
|
+
; overlay opened from inside a scroll box is still reachable after the box
|
|
134
|
+
; has clipped everything else — which is the whole point of deferring it.
|
|
135
|
+
fn paintOrderAt:[EVGElement] (root:EVGElement px:double py:double) {
|
|
136
|
+
clear order
|
|
137
|
+
clear deferred
|
|
138
|
+
this.collectAt(root px py)
|
|
139
|
+
def i:int 0
|
|
140
|
+
while (i < (array_length deferred)) {
|
|
141
|
+
this.collectAt((itemAt deferred i) px py)
|
|
142
|
+
i = (i + 1)
|
|
143
|
+
}
|
|
144
|
+
return order
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
; The id of the topmost element under the point that HAS one.
|
|
148
|
+
;
|
|
149
|
+
; Unnamed elements are passed over rather than answered with "": a label
|
|
150
|
+
; inside a row is drawn last and would otherwise swallow every click on the
|
|
151
|
+
; row that owns it. Giving a thing an id is how this file is told the thing
|
|
152
|
+
; is a target — the same convention `UiHost` uses with test ids.
|
|
153
|
+
fn idAt:string (root:EVGElement px:double py:double) {
|
|
154
|
+
def list:[EVGElement] (this.paintOrderAt(root px py))
|
|
155
|
+
def i:int ((array_length list) - 1)
|
|
156
|
+
while (i >= 0) {
|
|
157
|
+
def el:EVGElement (itemAt list i)
|
|
158
|
+
if ((strlen el.id) > 0) {
|
|
159
|
+
if (EVGHitTest.containsPoint(el px py)) {
|
|
160
|
+
return el.id
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
i = (i - 1)
|
|
164
|
+
}
|
|
165
|
+
return ""
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
; What the pointer should look like here.
|
|
169
|
+
;
|
|
170
|
+
; The topmost element under the point, whatever its id — unlike `idAt` this
|
|
171
|
+
; does NOT skip the unnamed ones, because a label inside a title bar is
|
|
172
|
+
; exactly the thing the pointer is usually over and it has no id of its
|
|
173
|
+
; own. It does not need one: `cursor` inherits, so by the time the layout
|
|
174
|
+
; is done the label is carrying its bar's answer.
|
|
175
|
+
;
|
|
176
|
+
; Empty means nobody said, and the caller decides what that means.
|
|
177
|
+
fn cursorAt:string (root:EVGElement px:double py:double) {
|
|
178
|
+
def list:[EVGElement] (this.paintOrderAt(root px py))
|
|
179
|
+
def i:int ((array_length list) - 1)
|
|
180
|
+
while (i >= 0) {
|
|
181
|
+
def el:EVGElement (itemAt list i)
|
|
182
|
+
if ((strlen el.cursor) > 0) {
|
|
183
|
+
if (EVGHitTest.containsPoint(el px py)) {
|
|
184
|
+
return el.cursor
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
i = (i - 1)
|
|
188
|
+
}
|
|
189
|
+
return ""
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
; Same scan, for a caller that wants the class list — a hover highlight asks
|
|
193
|
+
; "is this a row?" and does not care which row.
|
|
194
|
+
fn classAt:string (root:EVGElement px:double py:double) {
|
|
195
|
+
def list:[EVGElement] (this.paintOrderAt(root px py))
|
|
196
|
+
def i:int ((array_length list) - 1)
|
|
197
|
+
while (i >= 0) {
|
|
198
|
+
def el:EVGElement (itemAt list i)
|
|
199
|
+
if ((strlen el.id) > 0) {
|
|
200
|
+
if (EVGHitTest.containsPoint(el px py)) {
|
|
201
|
+
return el.className
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
i = (i - 1)
|
|
205
|
+
}
|
|
206
|
+
return ""
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; =============================================================================
|
|
4
|
+
; EVGHoles / EVGDress — a `{key}` in a document, and what fills it in a design
|
|
5
|
+
; =============================================================================
|
|
6
|
+
;
|
|
7
|
+
; A document that drives an app writes a control's state as a HOLE:
|
|
8
|
+
;
|
|
9
|
+
; class-name="ui-switch ui-switch-state-{wifi}"
|
|
10
|
+
;
|
|
11
|
+
; At run time a machine fills it from its context, and the class becomes
|
|
12
|
+
; `ui-switch-state-checked`, which is what the stylesheet paints. That is the
|
|
13
|
+
; app runtime's job and it lives with the app runtime.
|
|
14
|
+
;
|
|
15
|
+
; At DESIGN time there is no machine, and until now the hole was left exactly
|
|
16
|
+
; as written — so `ui-switch-state-{wifi}` matched no rule, the track got no
|
|
17
|
+
; colour and the switch was invisible on the very screen somebody was drawing.
|
|
18
|
+
; The workaround people found was to hand-write base paint into the document's
|
|
19
|
+
; stylesheet so the unmatched state would not matter. That is a second copy of
|
|
20
|
+
; every control's look, kept in step by hand, and it is what this file exists
|
|
21
|
+
; to make unnecessary.
|
|
22
|
+
;
|
|
23
|
+
; The document already knows what each control is showing: `checked` is on the
|
|
24
|
+
; node, and it is the same value `evg_app init` reads to write the machine's
|
|
25
|
+
; opening context. So a design can fill its own holes from itself, and the
|
|
26
|
+
; picture a designer sees is the picture the app boots with.
|
|
27
|
+
;
|
|
28
|
+
; It fills by ADDING, never by replacing:
|
|
29
|
+
;
|
|
30
|
+
; ui-switch-track-state-{wifi}
|
|
31
|
+
; ui-switch-track-state-{wifi} ui-switch-track-state-checked
|
|
32
|
+
;
|
|
33
|
+
; The hole stays in the class list, which matters for three reasons. Nothing
|
|
34
|
+
; downstream can mistake a dressed design for a bound app. `EVGMeasure` can
|
|
35
|
+
; still tell a control that is bound from one whose state is a fixed word —
|
|
36
|
+
; the `frozen` check reads exactly that. And the document on disk is never
|
|
37
|
+
; touched: this dresses a tree in memory, on its way to a layout.
|
|
38
|
+
;
|
|
39
|
+
; The app runtime does NOT call this. A machine's value and the document's
|
|
40
|
+
; value disagree the moment anything is pressed, and two state classes on one
|
|
41
|
+
; element would then paint whichever the sheet happened to reach last.
|
|
42
|
+
; =============================================================================
|
|
43
|
+
|
|
44
|
+
Import "EVGElement.rgr"
|
|
45
|
+
|
|
46
|
+
class EVGHoles {
|
|
47
|
+
; --- THE TWO SHAPES OF A HOLE ---------------------------------------------
|
|
48
|
+
;
|
|
49
|
+
; {wifi} the key's value, whatever it is
|
|
50
|
+
; {cinematic=4k30} "checked" when the key IS that value, else "unchecked"
|
|
51
|
+
;
|
|
52
|
+
; The second exists because one thing a screen does constantly has no
|
|
53
|
+
; expression in the first: CHOOSING ONE OF SEVERAL. A list of six
|
|
54
|
+
; resolutions with a tick against the chosen one is not six switches —
|
|
55
|
+
; it is one value, asked six different questions. Encoded with plain
|
|
56
|
+
; holes it becomes a key per row that something has to keep consistent,
|
|
57
|
+
; and the thing that has to is a person, who will get it wrong.
|
|
58
|
+
;
|
|
59
|
+
; Asking the question in the hole keeps the fact in one place. The answer
|
|
60
|
+
; is a STATE WORD rather than a boolean because that is the vocabulary
|
|
61
|
+
; every control in this engine already paints with, so a tick needs two
|
|
62
|
+
; rules in the sheet — `.check-state-checked`, `.check-state-unchecked` —
|
|
63
|
+
; and those two serve every row of every group in the app.
|
|
64
|
+
;
|
|
65
|
+
; A key with a `=` in it is not addressable, which is the price and is
|
|
66
|
+
; cheap: `=` is not in any key anybody writes.
|
|
67
|
+
sfn keyOf:string (name:string) {
|
|
68
|
+
def cut:int (indexOf name "=")
|
|
69
|
+
if (cut < 0) {
|
|
70
|
+
return name
|
|
71
|
+
}
|
|
72
|
+
return (substring name 0 cut)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
; "" when the hole asks for the value rather than testing it.
|
|
76
|
+
sfn wantOf:string (name:string) {
|
|
77
|
+
def cut:int (indexOf name "=")
|
|
78
|
+
if (cut < 0) {
|
|
79
|
+
return ""
|
|
80
|
+
}
|
|
81
|
+
return (substring name (cut + 1) (strlen name))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
sfn asksEquals:boolean (name:string) {
|
|
85
|
+
return ((indexOf name "=") >= 0)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
; The `{name}` syntax, defined once. `EvgAppRules.fillText` fills the same
|
|
89
|
+
; holes from a machine's context; it differs only in where the value comes
|
|
90
|
+
; from, and it scans with this.
|
|
91
|
+
;
|
|
92
|
+
; A `{key=value}` reports `key`: the name a machine has to hold is the
|
|
93
|
+
; key, and the value is the question being asked about it.
|
|
94
|
+
sfn scan:void (text:string out:[string]) {
|
|
95
|
+
def n:int (strlen text)
|
|
96
|
+
def i@(mutable):int 0
|
|
97
|
+
while (i < n) {
|
|
98
|
+
if ((charAt text i) == 123) {
|
|
99
|
+
def j@(mutable):int (i + 1)
|
|
100
|
+
def close@(mutable):int (0 - 1)
|
|
101
|
+
while (j < n) {
|
|
102
|
+
if ((charAt text j) == 125) {
|
|
103
|
+
if (close < 0) {
|
|
104
|
+
close = j
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
j = (j + 1)
|
|
108
|
+
}
|
|
109
|
+
if (close < 0) {
|
|
110
|
+
i = n
|
|
111
|
+
} {
|
|
112
|
+
def name:string (substring text (i + 1) close)
|
|
113
|
+
def key:string (EVGHoles.keyOf(name))
|
|
114
|
+
if ((strlen key) > 0) {
|
|
115
|
+
if ((EVGHoles.mentions(out key)) == false) {
|
|
116
|
+
push out key
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
i = (close + 1)
|
|
120
|
+
}
|
|
121
|
+
} {
|
|
122
|
+
i = (i + 1)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
; Every hole in `text` replaced by one word. A design has a single answer
|
|
128
|
+
; for a control — what it is showing — so it does not need a per-key
|
|
129
|
+
; lookup, and an unclosed `{` is left alone rather than swallowing the
|
|
130
|
+
; rest of the string.
|
|
131
|
+
sfn fillWith:string (text:string word:string) {
|
|
132
|
+
def out@(mutable):string ""
|
|
133
|
+
def i@(mutable):int 0
|
|
134
|
+
def n:int (strlen text)
|
|
135
|
+
while (i < n) {
|
|
136
|
+
def c:int (charAt text i)
|
|
137
|
+
if (c == 123) {
|
|
138
|
+
def close@(mutable):int (0 - 1)
|
|
139
|
+
def j@(mutable):int (i + 1)
|
|
140
|
+
while (j < n) {
|
|
141
|
+
if ((charAt text j) == 125) {
|
|
142
|
+
if (close < 0) {
|
|
143
|
+
close = j
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
j = (j + 1)
|
|
147
|
+
}
|
|
148
|
+
if (close < 0) {
|
|
149
|
+
out = (out + (substring text i (i + 1)))
|
|
150
|
+
i = (i + 1)
|
|
151
|
+
} {
|
|
152
|
+
out = (out + word)
|
|
153
|
+
i = (close + 1)
|
|
154
|
+
}
|
|
155
|
+
} {
|
|
156
|
+
out = (out + (substring text i (i + 1)))
|
|
157
|
+
i = (i + 1)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return out
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
sfn hasHole:boolean (text:string) {
|
|
164
|
+
return ((indexOf text "{") >= 0)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
sfn mentions:boolean (list:[string] want:string) {
|
|
168
|
+
def i:int 0
|
|
169
|
+
while (i < (array_length list)) {
|
|
170
|
+
if ((itemAt list i) == want) {
|
|
171
|
+
return true
|
|
172
|
+
}
|
|
173
|
+
i = (i + 1)
|
|
174
|
+
}
|
|
175
|
+
return false
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
class EVGDress {
|
|
180
|
+
; Fill a design's own state holes, in place, on a tree that is on its way
|
|
181
|
+
; to a layout. Safe to call twice: a class that is already there is not
|
|
182
|
+
; added again.
|
|
183
|
+
sfn dress:void (root:EVGElement) {
|
|
184
|
+
EVGDress.walk(root "")
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
; The state word flows DOWN. A track and a thumb carry the same hole as the
|
|
188
|
+
; switch above them and say nothing themselves about what they are showing,
|
|
189
|
+
; because the control is the thing that has a state — so the nearest
|
|
190
|
+
; ancestor with a role is what answers for them.
|
|
191
|
+
sfn walk:void (el:EVGElement word:string) {
|
|
192
|
+
def here:string word
|
|
193
|
+
if ((strlen el.role) > 0) {
|
|
194
|
+
def own:string (EVGDress.wordFor(el))
|
|
195
|
+
if ((strlen own) > 0) {
|
|
196
|
+
here = own
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if ((strlen here) > 0) {
|
|
200
|
+
if ((strlen el.className) > 0) {
|
|
201
|
+
el.className = (EVGDress.dressed(el.className here))
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
def i:int 0
|
|
205
|
+
while (i < (array_length el.children)) {
|
|
206
|
+
EVGDress.walk((itemAt el.children i) here)
|
|
207
|
+
i = (i + 1)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
; What this control is showing, as the word a state class is spelled with.
|
|
212
|
+
; A control that says nothing is showing `unchecked`: that is what a
|
|
213
|
+
; machine written by `evg_app init` opens with, so it is what a design of
|
|
214
|
+
; it should look like rather than a hole.
|
|
215
|
+
sfn wordFor:string (el:EVGElement) {
|
|
216
|
+
if (el.a11yChecked == 2) {
|
|
217
|
+
return "checked"
|
|
218
|
+
}
|
|
219
|
+
if (el.a11yChecked == 3) {
|
|
220
|
+
return "indeterminate"
|
|
221
|
+
}
|
|
222
|
+
if (el.a11yChecked == 1) {
|
|
223
|
+
return "unchecked"
|
|
224
|
+
}
|
|
225
|
+
if (EVGDress.isStateful(el.role)) {
|
|
226
|
+
return "unchecked"
|
|
227
|
+
}
|
|
228
|
+
return ""
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
sfn isStateful:boolean (role:string) {
|
|
232
|
+
if (role == "switch") {
|
|
233
|
+
return true
|
|
234
|
+
}
|
|
235
|
+
if (role == "checkbox") {
|
|
236
|
+
return true
|
|
237
|
+
}
|
|
238
|
+
if (role == "radio") {
|
|
239
|
+
return true
|
|
240
|
+
}
|
|
241
|
+
return false
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
; Each holed class token gets a filled copy beside it. The hole itself
|
|
245
|
+
; stays: see the header — this is the difference between a design that
|
|
246
|
+
; paints and a design that has quietly become an app.
|
|
247
|
+
sfn dressed:string (className:string word:string) {
|
|
248
|
+
if ((EVGHoles.hasHole(className)) == false) {
|
|
249
|
+
return className
|
|
250
|
+
}
|
|
251
|
+
def out@(mutable):string className
|
|
252
|
+
def n:int (strlen className)
|
|
253
|
+
def at@(mutable):int 0
|
|
254
|
+
while (at < n) {
|
|
255
|
+
def rest:string (substring className at n)
|
|
256
|
+
def sp:int (indexOf rest " ")
|
|
257
|
+
def end@(mutable):int n
|
|
258
|
+
if (sp >= 0) {
|
|
259
|
+
end = (at + sp)
|
|
260
|
+
}
|
|
261
|
+
def tok:string (substring className at end)
|
|
262
|
+
if (EVGHoles.hasHole(tok)) {
|
|
263
|
+
def filled:string (EVGHoles.fillWith(tok word))
|
|
264
|
+
if (filled != tok) {
|
|
265
|
+
if ((EVGDress.carries(out filled)) == false) {
|
|
266
|
+
out = ((out + " ") + filled)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
at = (end + 1)
|
|
271
|
+
}
|
|
272
|
+
return out
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
; Is `want` already one of the space-separated tokens of `className`?
|
|
276
|
+
; `indexOf` would say yes to `ui-switch` inside `ui-switch-track`.
|
|
277
|
+
sfn carries:boolean (className:string want:string) {
|
|
278
|
+
def n:int (strlen className)
|
|
279
|
+
def at@(mutable):int 0
|
|
280
|
+
while (at < n) {
|
|
281
|
+
def rest:string (substring className at n)
|
|
282
|
+
def sp:int (indexOf rest " ")
|
|
283
|
+
def end@(mutable):int n
|
|
284
|
+
if (sp >= 0) {
|
|
285
|
+
end = (at + sp)
|
|
286
|
+
}
|
|
287
|
+
if ((substring className at end) == want) {
|
|
288
|
+
return true
|
|
289
|
+
}
|
|
290
|
+
at = (end + 1)
|
|
291
|
+
}
|
|
292
|
+
return false
|
|
293
|
+
}
|
|
294
|
+
}
|