diff --git a/docs/_javascript/filter_tool.js b/docs/_javascript/filter_tool.js index f0f1e2e7..1d905d8d 100644 --- a/docs/_javascript/filter_tool.js +++ b/docs/_javascript/filter_tool.js @@ -1802,6 +1802,42 @@ URL.revokeObjectURL(url); }); + const policyPanel = root.querySelector(".filter-policy"); + const policyGrid = policyPanel ? policyPanel.parentElement : null; + const policyMarker = document.createComment("policy-draft-home"); + const widePolicyLayout = global.matchMedia("(min-width: 90rem)"); + let policyRail = null; + let policySidebar = null; + + if (policyPanel && policyGrid) policyGrid.insertBefore(policyMarker, policyPanel); + + function placePolicyDraft() { + if (!policyPanel || !policyGrid) return; + const sidebar = document.querySelector(".md-sidebar--secondary"); + const sidebarInner = sidebar ? sidebar.querySelector(".md-sidebar__inner") : null; + if (widePolicyLayout.matches && sidebarInner) { + if (!policyRail) { + policyRail = document.createElement("div"); + policyRail.className = "filter-tool filter-policy-rail"; + policyRail.setAttribute("aria-label", "Policy draft"); + } + policySidebar = sidebar; + policySidebar.classList.add("filter-policy-sidebar"); + sidebarInner.appendChild(policyRail); + policyRail.appendChild(policyPanel); + root.classList.add("filter-policy-detached"); + return; + } + policyMarker.parentNode.insertBefore(policyPanel, policyMarker.nextSibling); + root.classList.remove("filter-policy-detached"); + if (policySidebar) policySidebar.classList.remove("filter-policy-sidebar"); + if (policyRail) policyRail.remove(); + policySidebar = null; + } + + widePolicyLayout.addEventListener("change", placePolicyDraft); + placePolicyDraft(); + const requestedExample = new URLSearchParams(global.location.search).get("example"); if (requestedExample && COMPLETE_EXAMPLES[requestedExample]) assignRules(clone(COMPLETE_EXAMPLES[requestedExample])); resetForm(); diff --git a/docs/_stylesheets/filter_tool.css b/docs/_stylesheets/filter_tool.css index c2bbb481..609c2624 100644 --- a/docs/_stylesheets/filter_tool.css +++ b/docs/_stylesheets/filter_tool.css @@ -177,6 +177,24 @@ align-items: start; } +.filter-tool.filter-policy-detached .filter-tool-grid { + grid-template-columns: minmax(0, 1fr); +} + +.filter-policy-rail { + margin: 1rem 0 2rem; +} + +.filter-policy-rail .filter-policy { + width: 100%; +} + +@media (min-width: 90rem) { + .md-sidebar--secondary.filter-policy-sidebar { + width: 20rem; + } +} + .filter-panel { min-width: 0; padding: 1rem; diff --git a/docs/filter_tool.md b/docs/filter_tool.md index 79d7c7ea..dc4b5f3e 100644 --- a/docs/filter_tool.md +++ b/docs/filter_tool.md @@ -50,11 +50,11 @@ in the simulator below. The examples draw from type= valueMatches - grp_dataOnly the named payload type + grp_dataOnly the named payload type; see every exact type below anyEvery payload type class:groupGRP_TXT and GRP_DATA class:loginREQ, RESPONSE, TXT_MSG, ANON_REQ, and PATH - class:otherEvery remaining payload type + class:otherEvery remaining payload type that is not group or login @@ -579,6 +579,30 @@ in the simulator below. The examples draw from +## Payload type reference + +Use an exact `type=` value when a rule should match only one payload type. +The class column shows which broader selector also matches it. + +| `type=` value | Payload | Class | +| --- | --- | --- | +| `req` | Request | `class:login` | +| `response` | Response | `class:login` | +| `txt_msg` | Peer text message | `class:login` | +| `ack` | Acknowledgment | `class:other` | +| `advert` | Node advertisement | `class:other` | +| `grp_txt` | Group-channel text | `class:group` | +| `grp_data` | Group-channel datagram | `class:group` | +| `anon_req` | Anonymous request | `class:login` | +| `path` | Returned path | `class:login` | +| `trace` | Path trace | `class:other` | +| `multipart` | One frame in a multipart sequence | `class:other` | +| `control` | Control or discovery data | `class:other` | +| `ota` | OTA-over-LoRa data | `class:other` | +| `13` | Reserved payload type 13 | `class:other` | +| `14` | Reserved payload type 14 | `class:other` | +| `raw_custom` | Application-defined raw data | `class:other` | + ## Proposed evaluation contract The simulator uses these rules: