UNPKG

@blossom-carousel/svelte

Version:

A native-scroll-first carousel component for Svelte.

74 lines (73 loc) 2.47 kB
import { SLIDE_ATTR } from "./vendor/navigation/index.js"; /** * Counts elements carrying the `data-blossom-slide` attribute in an HTML * string (the server-rendered output of a carousel's children snippet). * * A small tag-aware scanner rather than a bare regex, so that: * - text content that happens to contain the literal attribute name is not * counted, * - a `>` inside a quoted attribute value does not truncate the tag, * - comments are skipped. */ export function countSlideMarkers(html) { let count = 0; let i = 0; while (i < html.length) { if (html[i] !== "<") { i++; continue; } if (html.startsWith("<!--", i)) { const end = html.indexOf("-->", i + 4); if (end === -1) break; i = end + 3; continue; } // Only element open tags can carry attributes; skip closing tags, // doctype, and stray `<` in text. if (!/[a-zA-Z]/.test(html[i + 1] ?? "")) { i++; continue; } i++; while (i < html.length && !/[\s/>]/.test(html[i])) i++; // tag name let marked = false; while (i < html.length && html[i] !== ">") { const char = html[i]; if (char === '"' || char === "'") { const closing = html.indexOf(char, i + 1); if (closing === -1) return count; // malformed; bail out i = closing + 1; continue; } if (char === "=") { // Skip the value. Quoted values are handled by the branch above on // the next iteration; unquoted values run to whitespace or `>`. i++; while (i < html.length && /\s/.test(html[i])) i++; if (html[i] !== '"' && html[i] !== "'") { while (i < html.length && !/[\s>]/.test(html[i])) i++; } continue; } if (/[\s/]/.test(char)) { i++; continue; } const start = i; while (i < html.length && !/[\s/=>]/.test(html[i])) i++; if (html.slice(start, i) === SLIDE_ATTR) marked = true; } if (marked) count++; i++; } return count; }