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,177 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EVGCommands.rgr — everything an application can do, by name.
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
;
|
|
7
|
+
; This was the spreadsheet's and lived beside it, which was fine until the
|
|
8
|
+
; document editor needed the same thing: a named surface a host can enumerate,
|
|
9
|
+
; describe and invoke by string. It never mentioned a cell, so there was
|
|
10
|
+
; nothing to change but where it sits.
|
|
11
|
+
;
|
|
12
|
+
; "GridApp is the API" was true and not much use: a host had to know the method
|
|
13
|
+
; names, their argument lists, and which of them were meant to be called from
|
|
14
|
+
; outside. This is the surface that answers those questions — a table of named
|
|
15
|
+
; commands a host can ENUMERATE, describe to a user, and invoke by string.
|
|
16
|
+
;
|
|
17
|
+
; That table is also what makes custom tools possible. Ranger has no closures to
|
|
18
|
+
; hand a host, so a registered tool does not carry code: it carries a NAME, and
|
|
19
|
+
; running it records the invocation for the host to collect. The host polls
|
|
20
|
+
; `takeCustomCommand` in the loop it already runs, and does whatever it likes.
|
|
21
|
+
; It is a mailbox rather than a callback, which is the honest shape for a
|
|
22
|
+
; language without function values, and it survives the app being driven over a
|
|
23
|
+
; socket — where a callback could not have gone anyway.
|
|
24
|
+
;
|
|
25
|
+
; Ids are dotted and stable: `edit.copy`, `insert.row.above`. The label and the
|
|
26
|
+
; group are for the host's own menus; the key is documentation of what the app
|
|
27
|
+
; already binds, not a binding this table owns.
|
|
28
|
+
; ==============================================================================
|
|
29
|
+
|
|
30
|
+
class GridCommand {
|
|
31
|
+
def id:string ""
|
|
32
|
+
def label:string ""
|
|
33
|
+
def group:string ""
|
|
34
|
+
def key:string ""
|
|
35
|
+
; Commands that read an argument — `nav.goto` takes "B7" — so a host can
|
|
36
|
+
; tell which of them need to ask for something first.
|
|
37
|
+
def takesArg:boolean false
|
|
38
|
+
; Registered by the host rather than built in. Running one records it
|
|
39
|
+
; instead of doing anything.
|
|
40
|
+
def custom:boolean false
|
|
41
|
+
|
|
42
|
+
Constructor () {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class GridCommandTable {
|
|
47
|
+
def commands:[GridCommand]
|
|
48
|
+
|
|
49
|
+
Constructor () {
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn add:GridCommand (id:string label:string group:string key:string) {
|
|
53
|
+
def c:GridCommand (new GridCommand)
|
|
54
|
+
c.id = id
|
|
55
|
+
c.label = label
|
|
56
|
+
c.group = group
|
|
57
|
+
c.key = key
|
|
58
|
+
push commands c
|
|
59
|
+
return c
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fn addArg:GridCommand (id:string label:string group:string key:string) {
|
|
63
|
+
def c:GridCommand (this.add(id label group key))
|
|
64
|
+
c.takesArg = true
|
|
65
|
+
return c
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fn addCustom:GridCommand (id:string label:string group:string) {
|
|
69
|
+
def c:GridCommand (this.add(id label group ""))
|
|
70
|
+
c.custom = true
|
|
71
|
+
return c
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
fn count:int () {
|
|
75
|
+
return (array_length commands)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn at:GridCommand (i:int) {
|
|
79
|
+
if (i < 0) {
|
|
80
|
+
return (new GridCommand)
|
|
81
|
+
}
|
|
82
|
+
if (i >= (array_length commands)) {
|
|
83
|
+
return (new GridCommand)
|
|
84
|
+
}
|
|
85
|
+
return (itemAt commands i)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
fn find:GridCommand (id:string) {
|
|
89
|
+
def i:int 0
|
|
90
|
+
while (i < (array_length commands)) {
|
|
91
|
+
def c:GridCommand (itemAt commands i)
|
|
92
|
+
if (c.id == id) {
|
|
93
|
+
return c
|
|
94
|
+
}
|
|
95
|
+
i = (i + 1)
|
|
96
|
+
}
|
|
97
|
+
return (new GridCommand)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fn has:boolean (id:string) {
|
|
101
|
+
def c:GridCommand (this.find(id))
|
|
102
|
+
return ((strlen c.id) > 0)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
fn customCount:int () {
|
|
106
|
+
def n:int 0
|
|
107
|
+
def i:int 0
|
|
108
|
+
while (i < (array_length commands)) {
|
|
109
|
+
def c:GridCommand (itemAt commands i)
|
|
110
|
+
if c.custom {
|
|
111
|
+
n = (n + 1)
|
|
112
|
+
}
|
|
113
|
+
i = (i + 1)
|
|
114
|
+
}
|
|
115
|
+
return n
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fn customAt:GridCommand (idx:int) {
|
|
119
|
+
def n:int 0
|
|
120
|
+
def i:int 0
|
|
121
|
+
while (i < (array_length commands)) {
|
|
122
|
+
def c:GridCommand (itemAt commands i)
|
|
123
|
+
if c.custom {
|
|
124
|
+
if (n == idx) {
|
|
125
|
+
return c
|
|
126
|
+
}
|
|
127
|
+
n = (n + 1)
|
|
128
|
+
}
|
|
129
|
+
i = (i + 1)
|
|
130
|
+
}
|
|
131
|
+
return (new GridCommand)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
; The whole table as JSON — what a host over a socket asks for first.
|
|
135
|
+
fn toJson:string () {
|
|
136
|
+
def out:string "["
|
|
137
|
+
def i:int 0
|
|
138
|
+
while (i < (array_length commands)) {
|
|
139
|
+
def c:GridCommand (itemAt commands i)
|
|
140
|
+
if (i > 0) {
|
|
141
|
+
out = (out + ",")
|
|
142
|
+
}
|
|
143
|
+
out = (out + "{\"id\":\"" + c.id + "\",\"label\":\"" + (GridCommandTable.esc(c.label)) + "\",\"group\":\"" + c.group + "\"")
|
|
144
|
+
if ((strlen c.key) > 0) {
|
|
145
|
+
out = (out + ",\"key\":\"" + c.key + "\"")
|
|
146
|
+
}
|
|
147
|
+
if c.takesArg {
|
|
148
|
+
out = (out + ",\"takesArg\":true")
|
|
149
|
+
}
|
|
150
|
+
if c.custom {
|
|
151
|
+
out = (out + ",\"custom\":true")
|
|
152
|
+
}
|
|
153
|
+
out = (out + "}")
|
|
154
|
+
i = (i + 1)
|
|
155
|
+
}
|
|
156
|
+
return (out + "]")
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
sfn esc:string (s:string) {
|
|
160
|
+
def out:string ""
|
|
161
|
+
def i:int 0
|
|
162
|
+
while (i < (strlen s)) {
|
|
163
|
+
def ch:int (charAt s i)
|
|
164
|
+
if (ch == 34) {
|
|
165
|
+
out = (out + "\\\"")
|
|
166
|
+
} {
|
|
167
|
+
if (ch == 92) {
|
|
168
|
+
out = (out + "\\\\")
|
|
169
|
+
} {
|
|
170
|
+
out = (out + (strfromcode ch))
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
i = (i + 1)
|
|
174
|
+
}
|
|
175
|
+
return out
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
; SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
; ==============================================================================
|
|
4
|
+
; EVGComponent — an instance that outlives the tree it produces
|
|
5
|
+
; ==============================================================================
|
|
6
|
+
; `EVGReconcile` made an ELEMENT survive a rebuild. This makes the thing that
|
|
7
|
+
; BUILT it survive one, which is a different problem and the one that has to be
|
|
8
|
+
; solved before `state` means anything.
|
|
9
|
+
;
|
|
10
|
+
; The difference is worth stating precisely, because "keyed reconciliation"
|
|
11
|
+
; sounds like it should already cover this. A reconciler works on the OUTPUT:
|
|
12
|
+
; two trees exist, and it decides which of their nodes are the same node.
|
|
13
|
+
; Nothing in that process gives the builder anywhere to live. A function that
|
|
14
|
+
; returns a subtree starts from nothing every time it is called — so a value it
|
|
15
|
+
; would like to remember between calls has no home, and the code that wants to
|
|
16
|
+
; remember something has to push it up into a controller or a page. That is
|
|
17
|
+
; where `MenuCtl.pendingTid` lives, and `pendingMs` beside it: a 100ms submenu
|
|
18
|
+
; timer that belongs to ONE ROW, kept on the controller because a row is a
|
|
19
|
+
; function call and a function call cannot hold a clock.
|
|
20
|
+
;
|
|
21
|
+
; A component is that home. It is an ordinary Ranger class with ordinary
|
|
22
|
+
; fields, and the only thing this file adds is the guarantee that the same
|
|
23
|
+
; instance comes back on the next pass.
|
|
24
|
+
;
|
|
25
|
+
; --- HOW IT WORKS -------------------------------------------------------------
|
|
26
|
+
;
|
|
27
|
+
; host.beginPass()
|
|
28
|
+
; def root:EVGElement (myApp.render(host))
|
|
29
|
+
; host.endPass()
|
|
30
|
+
; reconciler.reconcile(live root)
|
|
31
|
+
;
|
|
32
|
+
; and inside the build, wherever a component is wanted:
|
|
33
|
+
;
|
|
34
|
+
; def row:TreeRow (cast (host.use(value (new TreeRow())) to:TreeRow))
|
|
35
|
+
; row.label = name
|
|
36
|
+
; surface.addChild((row.render()))
|
|
37
|
+
;
|
|
38
|
+
; `use` returns the instance registered under that path if there is one, and
|
|
39
|
+
; registers the fresh one otherwise — so the `new` on that line is a fallback
|
|
40
|
+
; that is thrown away on every pass after the first. That is one allocation per
|
|
41
|
+
; mounted component per frame, and it buys a call site with no factory
|
|
42
|
+
; registry, no reflection and no second name for the class. Ranger has no way
|
|
43
|
+
; to construct a class from a string, and inventing one for this would be a
|
|
44
|
+
; larger feature than the one being built.
|
|
45
|
+
;
|
|
46
|
+
; --- KEYS, AND WHY THEY ARE PATHS ---------------------------------------------
|
|
47
|
+
;
|
|
48
|
+
; A key identifies a component among its SIBLINGS, exactly as `EVGElement.key`
|
|
49
|
+
; identifies an element among its siblings. Two lists on one page may both have
|
|
50
|
+
; a row keyed "video". So the host keeps a path — `enter(segment)` on the way
|
|
51
|
+
; down, `leave()` on the way back — and the registry is keyed by the joined
|
|
52
|
+
; path. The caller never concatenates anything.
|
|
53
|
+
;
|
|
54
|
+
; A component that renders components therefore reads:
|
|
55
|
+
;
|
|
56
|
+
; host.enter(("row:" + value))
|
|
57
|
+
; ... children ask for plain keys ...
|
|
58
|
+
; host.leave()
|
|
59
|
+
;
|
|
60
|
+
; --- MOUNT, UPDATE, DISPOSE ---------------------------------------------------
|
|
61
|
+
;
|
|
62
|
+
; The same three events `EVGReconcileStats` counts for elements — kept, created,
|
|
63
|
+
; dropped — one level up, and named apart so a number says which layer it came
|
|
64
|
+
; from. `endPass` disposes everything that was not asked for during the pass,
|
|
65
|
+
; and that is the half a reconciler cannot do for you: dropping an element takes
|
|
66
|
+
; its subtree out of the tree and tells nobody, which is fine for a box and
|
|
67
|
+
; wrong for anything holding a timer, a pointer capture or a subscription.
|
|
68
|
+
;
|
|
69
|
+
; --- WHAT IDENTITY IS MISSING -------------------------------------------------
|
|
70
|
+
;
|
|
71
|
+
; A component's identity should be its parent, its CALL SITE and its key. This
|
|
72
|
+
; has the first and the third; a library cannot see the second. So two sibling
|
|
73
|
+
; calls with the same key are indistinguishable here from one component being
|
|
74
|
+
; rebuilt, and they would share an instance and its state. That is reported
|
|
75
|
+
; rather than absorbed — see `use`. Folding the call site in is a thing the
|
|
76
|
+
; compiler can do when `component` becomes a literal, and it is the reason to
|
|
77
|
+
; do it there rather than here.
|
|
78
|
+
;
|
|
79
|
+
; --- WHAT THIS IS NOT ---------------------------------------------------------
|
|
80
|
+
;
|
|
81
|
+
; There is no `state` keyword, no dependency tracking, and no decision about
|
|
82
|
+
; WHEN to re-render — every component's `view` runs on every pass. A field on a
|
|
83
|
+
; component subclass already survives, which is what makes `state` sugar rather
|
|
84
|
+
; than machinery when it arrives. Tracking which fields were read, and skipping
|
|
85
|
+
; the views that cannot have changed, is the step after this one.
|
|
86
|
+
; ==============================================================================
|
|
87
|
+
|
|
88
|
+
Import "EVGElement.rgr"
|
|
89
|
+
|
|
90
|
+
class EVGComponent {
|
|
91
|
+
|
|
92
|
+
; The name this instance is registered under, set by the host. A component
|
|
93
|
+
; never chooses its own — a thing cannot decide what it is called among
|
|
94
|
+
; siblings it does not know about.
|
|
95
|
+
def path:string ""
|
|
96
|
+
|
|
97
|
+
; How many times `render` has been called on THIS INSTANCE. Not a
|
|
98
|
+
; diagnostic: it is the cheapest possible proof that an instance survived a
|
|
99
|
+
; rebuild, and it is what the tests read.
|
|
100
|
+
def renders:int 0
|
|
101
|
+
|
|
102
|
+
Constructor () {
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
; What the component draws. Subclasses override this; nothing else here is
|
|
106
|
+
; meant to be.
|
|
107
|
+
fn view:EVGElement () {
|
|
108
|
+
return (EVGElement.createDiv())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
; Called once, when the host first registers this instance.
|
|
112
|
+
fn onMount:void () {
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
; Called once, when a pass ends without this instance having been asked
|
|
116
|
+
; for. After this the host forgets it, and asking again builds a new one.
|
|
117
|
+
;
|
|
118
|
+
; `dispose` and not `unmount`, because unmounting is what happens to the
|
|
119
|
+
; ELEMENT and this is what happens to the OWNER. A component may hold a
|
|
120
|
+
; timer, a pointer capture, a subscription or a pending request, and a key
|
|
121
|
+
; that leaves the tree must not leave any of them running: this is the only
|
|
122
|
+
; notification that a thing is gone, and the reconciler cannot give it —
|
|
123
|
+
; dropping an element takes a subtree out of the tree and tells nobody.
|
|
124
|
+
fn onDispose:void () {
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
; The view, plus the two things every component's root needs.
|
|
128
|
+
;
|
|
129
|
+
; Stamping the key here rather than leaving it to `view` is deliberate: the
|
|
130
|
+
; host and the reconciler have to agree about identity, and they agree by
|
|
131
|
+
; construction if the element's key is the component's path. A component
|
|
132
|
+
; whose view forgot the key would keep its own state and lose its element's
|
|
133
|
+
; — half-persistent, which is worse than neither.
|
|
134
|
+
fn render:EVGElement () {
|
|
135
|
+
renders = (renders + 1)
|
|
136
|
+
def el:EVGElement (this.view())
|
|
137
|
+
el.key = path
|
|
138
|
+
return el
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
; The component-level counterpart of `EVGReconcileStats`. Elements are kept,
|
|
143
|
+
; created and dropped; components are mounted, updated and disposed — the same
|
|
144
|
+
; three events one level up, and named differently on purpose so a number in a
|
|
145
|
+
; log says which layer it came from.
|
|
146
|
+
class EVGComponentStats {
|
|
147
|
+
def mounted:int 0
|
|
148
|
+
def updated:int 0
|
|
149
|
+
def disposed:int 0
|
|
150
|
+
; How many are registered right now. `live` and not `count`, because the
|
|
151
|
+
; number that matters is how many are being kept alive.
|
|
152
|
+
def live:int 0
|
|
153
|
+
|
|
154
|
+
Constructor () {
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
class EVGComponentHost {
|
|
159
|
+
|
|
160
|
+
; The registry. Parallel arrays plus an index, the same shape `DBOps` uses
|
|
161
|
+
; for a join: the map answers "is this path known", the arrays hold what is
|
|
162
|
+
; known, and `seen` is cleared at the start of every pass.
|
|
163
|
+
def paths:[string]
|
|
164
|
+
def comps:[EVGComponent]
|
|
165
|
+
def seen:[boolean]
|
|
166
|
+
def index:[string:int]
|
|
167
|
+
|
|
168
|
+
; Where the walk currently is. Joined with "/" to make a path.
|
|
169
|
+
def stack:[string]
|
|
170
|
+
|
|
171
|
+
def stats:EVGComponentStats (new EVGComponentStats())
|
|
172
|
+
; True between beginPass and endPass. `use` outside a pass is a mistake
|
|
173
|
+
; that would otherwise look like a component that never unmounts.
|
|
174
|
+
def inPass:boolean false
|
|
175
|
+
def problems:[string]
|
|
176
|
+
|
|
177
|
+
Constructor () {
|
|
178
|
+
def a:[string]
|
|
179
|
+
paths = a
|
|
180
|
+
def b:[EVGComponent]
|
|
181
|
+
comps = b
|
|
182
|
+
def c:[boolean]
|
|
183
|
+
seen = c
|
|
184
|
+
def d:[string:int]
|
|
185
|
+
index = d
|
|
186
|
+
def e:[string]
|
|
187
|
+
stack = e
|
|
188
|
+
def f:[string]
|
|
189
|
+
problems = f
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
fn beginPass:void () {
|
|
193
|
+
if inPass {
|
|
194
|
+
push problems "beginPass called twice without an endPass"
|
|
195
|
+
}
|
|
196
|
+
inPass = true
|
|
197
|
+
stats = (new EVGComponentStats())
|
|
198
|
+
def i:int 0
|
|
199
|
+
while (i < (array_length seen)) {
|
|
200
|
+
set_at seen i false
|
|
201
|
+
i = (i + 1)
|
|
202
|
+
}
|
|
203
|
+
def empty:[string]
|
|
204
|
+
stack = empty
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
fn enter:void (segment:string) {
|
|
208
|
+
push stack segment
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
fn leave:void () {
|
|
212
|
+
if ((array_length stack) == 0) {
|
|
213
|
+
push problems "leave() with nothing entered"
|
|
214
|
+
return
|
|
215
|
+
}
|
|
216
|
+
removeLast stack
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
; The path a `use(key …)` right here would land on. Public because a test
|
|
220
|
+
; that cannot say where a component went is a test of nothing.
|
|
221
|
+
fn pathFor:string (key:string) {
|
|
222
|
+
def out:string ""
|
|
223
|
+
def i:int 0
|
|
224
|
+
while (i < (array_length stack)) {
|
|
225
|
+
out = ((out + (itemAt stack i)) + "/")
|
|
226
|
+
i = (i + 1)
|
|
227
|
+
}
|
|
228
|
+
return (out + key)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
; The instance for `key` at the current path — the one from last pass if
|
|
232
|
+
; there is one, `fresh` otherwise.
|
|
233
|
+
fn use:EVGComponent (key:string fresh:EVGComponent) {
|
|
234
|
+
if (inPass == false) {
|
|
235
|
+
push problems ("use(" + key + ") outside a pass")
|
|
236
|
+
}
|
|
237
|
+
def path:string (this.pathFor(key))
|
|
238
|
+
def at@(optional):int (get index path)
|
|
239
|
+
if (null? at) {
|
|
240
|
+
def slot:int (array_length comps)
|
|
241
|
+
fresh.path = path
|
|
242
|
+
push paths path
|
|
243
|
+
push comps fresh
|
|
244
|
+
push seen true
|
|
245
|
+
set index path slot
|
|
246
|
+
stats.mounted = (stats.mounted + 1)
|
|
247
|
+
fresh.onMount()
|
|
248
|
+
return fresh
|
|
249
|
+
}
|
|
250
|
+
def slot2:int (unwrap at)
|
|
251
|
+
; Asked for TWICE in the same pass. A component's identity is its
|
|
252
|
+
; parent plus its key, and nothing here can see a call site — so two
|
|
253
|
+
; sibling calls with one key are indistinguishable from a rebuild of
|
|
254
|
+
; the same component, and both would silently share an instance and
|
|
255
|
+
; therefore share its state.
|
|
256
|
+
;
|
|
257
|
+
; Saying so is the honest fix at this layer. A compiler that lowers a
|
|
258
|
+
; `component` literal can fold the call site into the path and make the
|
|
259
|
+
; collision impossible; a library cannot, and quietly handing back the
|
|
260
|
+
; same object is the failure mode that looks like it works.
|
|
261
|
+
if (itemAt seen slot2) {
|
|
262
|
+
push problems (("two components asked for the same key in one pass: " + path) + " — give them different keys, or they will share state")
|
|
263
|
+
}
|
|
264
|
+
set_at seen slot2 true
|
|
265
|
+
stats.updated = (stats.updated + 1)
|
|
266
|
+
return (itemAt comps slot2)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
; Close the pass, and unmount whatever nobody asked for.
|
|
270
|
+
;
|
|
271
|
+
; The rebuild is what removes a component: there is no `remove` call and
|
|
272
|
+
; there should not be one. Something disappears from a view by not being
|
|
273
|
+
; built, and anything that has to happen when it does is this method's job
|
|
274
|
+
; — which is the whole reason a component is more than a function.
|
|
275
|
+
fn endPass:void () {
|
|
276
|
+
if (inPass == false) {
|
|
277
|
+
push problems "endPass without a beginPass"
|
|
278
|
+
}
|
|
279
|
+
if ((array_length stack) != 0) {
|
|
280
|
+
push problems "endPass with an unclosed enter()"
|
|
281
|
+
}
|
|
282
|
+
inPass = false
|
|
283
|
+
|
|
284
|
+
def keptPaths:[string]
|
|
285
|
+
def keptComps:[EVGComponent]
|
|
286
|
+
def keptSeen:[boolean]
|
|
287
|
+
def fresh:[string:int]
|
|
288
|
+
def i:int 0
|
|
289
|
+
while (i < (array_length comps)) {
|
|
290
|
+
def c:EVGComponent (itemAt comps i)
|
|
291
|
+
if (itemAt seen i) {
|
|
292
|
+
def slot:int (array_length keptComps)
|
|
293
|
+
push keptPaths (itemAt paths i)
|
|
294
|
+
push keptComps c
|
|
295
|
+
push keptSeen true
|
|
296
|
+
set fresh (itemAt paths i) slot
|
|
297
|
+
} {
|
|
298
|
+
stats.disposed = (stats.disposed + 1)
|
|
299
|
+
c.onDispose()
|
|
300
|
+
}
|
|
301
|
+
i = (i + 1)
|
|
302
|
+
}
|
|
303
|
+
paths = keptPaths
|
|
304
|
+
comps = keptComps
|
|
305
|
+
seen = keptSeen
|
|
306
|
+
index = fresh
|
|
307
|
+
stats.live = (array_length comps)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
; Everything registered, for a test or a page that wants to look.
|
|
311
|
+
fn livePaths:[string] () {
|
|
312
|
+
return paths
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
fn find@(optional):EVGComponent (path:string) {
|
|
316
|
+
def at@(optional):int (get index path)
|
|
317
|
+
if (null? at) {
|
|
318
|
+
def miss@(optional):EVGComponent
|
|
319
|
+
return miss
|
|
320
|
+
}
|
|
321
|
+
def hit@(optional):EVGComponent (itemAt comps (unwrap at))
|
|
322
|
+
return hit
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
; Misuse, in the host's own words. Same idea as `EVGA11yTree.notes`: a
|
|
326
|
+
; mistake that produces a plausible-looking result is one that has to
|
|
327
|
+
; announce itself, because nothing downstream will.
|
|
328
|
+
fn lint:[string] () {
|
|
329
|
+
return problems
|
|
330
|
+
}
|
|
331
|
+
}
|