From acab75e78af244f8cd9d5abff06020451fcdbdc2 Mon Sep 17 00:00:00 2001 From: Peter Rushforth Date: Thu, 7 May 2026 20:29:03 -0400 Subject: [PATCH 1/2] Implement search control UI Make icons a bit bolder to match the search icon which is paths of a certain width Add disabled support to search control. Bound to checked, but not bound to hidden. Update linux screenshots due to bolding of zoom, reload controls to match magnifying glass search control icon boldness. Remove now out of date win32 screenshots for same reason Make calculation of total size of controls omit the search control mostly, for backwards compatibility Add waitUntil: 'networkidle', increase some timeouts to de-flake some tests Implement custom search handler. Use geoname search as example. Add search example using geonames.org Search panel grabs focus on mouseenter Add localization messages for search button. Add localization and non-Latin character search tests. Add second search layer to index.html mapml-viewer (multiple search link handler) Change search default - clicking a suggestion triggers a search, navigation - panel stays open until user dismisses it - panel now requires 2 Esc / clicks to close it - update broken tests Simplify search events' API Add HTMLMapmlViewerElement.zoomToExtent(xmin,ymin,xmax,ymax) to support documentation change for custom search handler development De-flake a test Update markup skills to add search controlslist token De-flake a couple more tests Update win32 screen caps to account for bold control icons to match search icon boldness Clean up --- .github/skills/map-link-markup/SKILL.md | 204 +++++++ .github/skills/mapml-viewer-markup/SKILL.md | 2 +- index.html | 141 ++++- package-lock.json | 21 +- package.json | 6 +- src/map-link.js | 10 +- src/mapml-viewer.js | 33 +- src/mapml.css | 111 +++- src/mapml/control/SearchButton.js | 565 ++++++++++++++++++ src/web-map.js | 33 +- test/e2e/api/domApi-mapml-viewer.test.js | 69 +++ test/e2e/api/domApi-web-map.test.js | 63 ++ test/e2e/api/events/map-change-event.test.js | 4 +- test/e2e/api/locateApi.test.js | 3 +- test/e2e/core/searchCustomHandler.html | 70 +++ test/e2e/core/searchCustomHandler.test.js | 149 +++++ test/e2e/core/searchDefault.html | 28 + test/e2e/core/searchDefault.test.js | 187 ++++++ test/e2e/core/searchDisabled.html | 28 + test/e2e/core/searchDisabled.test.js | 179 ++++++ test/e2e/core/searchI18n.html | 28 + test/e2e/core/searchI18n.test.js | 75 +++ test/e2e/core/searchMultiLayer.html | 107 ++++ test/e2e/core/searchMultiLayer.test.js | 150 +++++ test/e2e/data/no-search-layer.mapml | 13 + test/e2e/data/search-geonames.mapml | 15 + test/e2e/data/search-geonames2.mapml | 15 + test/e2e/data/search-japanese.mapml | 14 + test/e2e/data/search-layer.mapml | 14 + test/e2e/data/search-with-tref.mapml | 15 + .../no-zinger-linux.png | Bin 10801 -> 9852 bytes .../no-zinger-win32.png | Bin 10670 -> 9744 bytes .../default-styled-markers-linux.png | Bin 9793 -> 9718 bytes .../default-styled-markers-win32.png | Bin 9712 -> 9714 bytes .../pmtiles-dark-linux.png | Bin 64806 -> 59457 bytes .../pmtiles-dark-win32.png | Bin 63948 -> 58817 bytes .../pmtiles-light-linux.png | Bin 73553 -> 74159 bytes .../pmtiles-light-win32.png | Bin 73553 -> 73587 bytes .../pmtiles-local-light-linux.png | Bin 81664 -> 74159 bytes .../pmtiles-local-light-win32.png | Bin 80855 -> 73587 bytes .../after-adding-tile-linux.png | Bin 19716 -> 19702 bytes .../after-adding-tile-win32.png | Bin 0 -> 19477 bytes .../after-src-change-linux.png | Bin 19963 -> 19943 bytes .../after-src-change-win32.png | Bin 0 -> 19690 bytes .../after-tile-removal-linux.png | Bin 18504 -> 18429 bytes .../after-tile-removal-win32.png | Bin 0 -> 18195 bytes .../baseline-before-adding-linux.png | Bin 19716 -> 19702 bytes .../baseline-before-adding-win32.png | Bin 0 -> 19477 bytes .../before-src-change-linux.png | Bin 19716 -> 19702 bytes .../before-src-change-win32.png | Bin 0 -> 19477 bytes .../before-tile-removal-linux.png | Bin 19716 -> 19702 bytes .../before-tile-removal-win32.png | Bin 0 -> 19477 bytes .../elements/map/map-in-shadow-root.test.js | 6 +- test/e2e/layers/general/isVisible.js | 2 +- test/e2e/layers/general/zoomLimit.js | 2 +- .../mixedLayer-baseline-linux.png | Bin 17676 -> 17694 bytes .../mixedLayer-baseline-win32.png | Bin 0 -> 17539 bytes .../mixedLayer-blue-checked-linux.png | Bin 28902 -> 28902 bytes .../mixedLayer-blue-checked-win32.png | Bin 0 -> 28856 bytes .../mixedLayer-dom-reordered-linux.png | Bin 17676 -> 17694 bytes .../mixedLayer-dom-reordered-win32.png | Bin 0 -> 17539 bytes .../mixedLayer-features-baseline-linux.png | Bin 17676 -> 17694 bytes .../mixedLayer-features-baseline-win32.png | Bin 0 -> 17539 bytes .../mixedLayer-hierarchy-validation-linux.png | Bin 17676 -> 17694 bytes .../mixedLayer-hierarchy-validation-win32.png | Bin 0 -> 17539 bytes .../mixedLayer-red-unchecked-linux.png | Bin 17705 -> 17753 bytes .../mixedLayer-red-unchecked-win32.png | Bin 0 -> 17574 bytes test/e2e/layers/templatedFeatures.test.js | 6 +- .../layers/templatedPMTilesMVTLayer.test.js | 31 +- .../mvt-blank-linux.png | Bin 3757 -> 3415 bytes .../mvt-blank-win32.png | Bin 3757 -> 3415 bytes .../mvt-custom-spearfish-linux.png | Bin 144623 -> 144557 bytes .../mvt-custom-spearfish-win32.png | Bin 142875 -> 142940 bytes .../mvt-light-linux.png | Bin 46537 -> 42836 bytes .../mvt-light-win32.png | Bin 43412 -> 39133 bytes .../mvt-light-z2-linux.png | Bin 68360 -> 62776 bytes .../mvt-light-z2-win32.png | Bin 65897 -> 59271 bytes .../pmtiles-dark-linux.png | Bin 45119 -> 41513 bytes .../pmtiles-dark-win32.png | Bin 42417 -> 38164 bytes .../pmtiles-dark-z10-linux.png | Bin 45768 -> 42331 bytes .../pmtiles-dark-z10-win32.png | Bin 45419 -> 42030 bytes test/e2e/mapml-viewer/customTCRS.test.js | 4 +- test/e2e/mapml-viewer/localization.html | 11 +- test/e2e/mapml-viewer/localization.test.js | 46 +- test/e2e/mapml-viewer/mapml-viewer.test.js | 60 ++ test/e2e/web-map/map.test.js | 57 ++ test/server.js | 187 ++++++ 87 files changed, 2704 insertions(+), 60 deletions(-) create mode 100644 src/mapml/control/SearchButton.js create mode 100644 test/e2e/core/searchCustomHandler.html create mode 100644 test/e2e/core/searchCustomHandler.test.js create mode 100644 test/e2e/core/searchDefault.html create mode 100644 test/e2e/core/searchDefault.test.js create mode 100644 test/e2e/core/searchDisabled.html create mode 100644 test/e2e/core/searchDisabled.test.js create mode 100644 test/e2e/core/searchI18n.html create mode 100644 test/e2e/core/searchI18n.test.js create mode 100644 test/e2e/core/searchMultiLayer.html create mode 100644 test/e2e/core/searchMultiLayer.test.js create mode 100644 test/e2e/data/no-search-layer.mapml create mode 100644 test/e2e/data/search-geonames.mapml create mode 100644 test/e2e/data/search-geonames2.mapml create mode 100644 test/e2e/data/search-japanese.mapml create mode 100644 test/e2e/data/search-layer.mapml create mode 100644 test/e2e/data/search-with-tref.mapml create mode 100644 test/e2e/elements/map-tile/map-tile.test.js-snapshots/after-adding-tile-win32.png create mode 100644 test/e2e/elements/map-tile/map-tile.test.js-snapshots/after-src-change-win32.png create mode 100644 test/e2e/elements/map-tile/map-tile.test.js-snapshots/after-tile-removal-win32.png create mode 100644 test/e2e/elements/map-tile/map-tile.test.js-snapshots/baseline-before-adding-win32.png create mode 100644 test/e2e/elements/map-tile/map-tile.test.js-snapshots/before-src-change-win32.png create mode 100644 test/e2e/elements/map-tile/map-tile.test.js-snapshots/before-tile-removal-win32.png create mode 100644 test/e2e/layers/mixedLayer-zindex-rendering.test.js-snapshots/mixedLayer-baseline-win32.png create mode 100644 test/e2e/layers/mixedLayer-zindex-rendering.test.js-snapshots/mixedLayer-blue-checked-win32.png create mode 100644 test/e2e/layers/mixedLayer-zindex-rendering.test.js-snapshots/mixedLayer-dom-reordered-win32.png create mode 100644 test/e2e/layers/mixedLayer-zindex-rendering.test.js-snapshots/mixedLayer-features-baseline-win32.png create mode 100644 test/e2e/layers/mixedLayer-zindex-rendering.test.js-snapshots/mixedLayer-hierarchy-validation-win32.png create mode 100644 test/e2e/layers/mixedLayer-zindex-rendering.test.js-snapshots/mixedLayer-red-unchecked-win32.png diff --git a/.github/skills/map-link-markup/SKILL.md b/.github/skills/map-link-markup/SKILL.md index 73692253e..32f648c9f 100644 --- a/.github/skills/map-link-markup/SKILL.md +++ b/.github/skills/map-link-markup/SKILL.md @@ -37,6 +37,8 @@ defines several uses of existing and new `rel` keyword values. | `zoomout` | The link `href` is followed automatically by the polyfill when the map is zoomed out by the user to a value less than the minimum value of the zoom range of the current layer. The referenced map layer resource replaces the current map layer. The polyfill does not represent this link as a user-visible affordance, it is followed automatically. If the remote resource does not contain a reciprocal `zoomin` link, the map state change is one-way i.e. the layer is permanently replaced. | | `legend` | The `legend` link relation designates a link to metadata, typically an image, describing the symbology used by the current layer. Currently, the polyfill creates a hyperlink for the label of the layer in the layer control, which opens in a new browsing context. | | `query` | The `query` link relation is used in combination with the `tref="..."` attribute to establish a URL template that composes a map query URL based on user map gestures such as click or touch. These URLs are fetched and the response presented on top of the map as a popup. Such queries can return text/html or text/mapml responses. In the latter case, the response may contain more than one feature, in which case a 'paged' popup is generated, allowing the user to cycle through the features' individual metadata. | +| `search` | The `search` link relation is used with the `tref="..."` attribute to define a URL template for a search endpoint. The template must contain the `{searchTerms}` variable reference, which is replaced with the user's URL-encoded search query. The search is triggered when the user presses Enter or clicks a suggestion. The response is expected to be a GeoJSON `FeatureCollection` (the default handler format). Only the first `