X-Git-Url: https://git.ayoreis.com/relax.git/blobdiff_plain/d7baaea4f90491d77b416fbf53935e090bbf7f7f..18760afc494c80d43ef455b9ef21859069936963:/relax/url-pattern-compare-component.ts?ds=inline diff --git a/relax/url-pattern-compare-component.ts b/relax/url-pattern-compare-component.ts index e69de29..76f8c85 100644 --- a/relax/url-pattern-compare-component.ts +++ b/relax/url-pattern-compare-component.ts @@ -0,0 +1,67 @@ +import type { COMPONENTS } from "./url-pattern-list.ts"; +import { + DEFAULT_OPTIONS, + HOSTNAME_OPTIONS, + parse_a_pattern_string, + Part, + PATHNAME_OPTIONS, +} from "./url-pattern-pattern-string-parser.ts"; + +const FINAL_PART = new Part("fixed-text", "", "none"); +const TYPE_SPECIFICITY = { + "fixed-text": 3, + "regexp": 2, + "segment-wildcard": 1, + "full-wildcard": 0, +} as const; +const MODIFIER_SPECIFICITY = { + "none": 3, + "one-or-more": 2, + "optional": 1, + "zero-or-more": 0, +} as const; + +/** https://github.com/whatwg/urlpattern/issues/61#issuecomment-887000984' */ +export function compareComponent( + component: typeof COMPONENTS[number], + left: URLPattern, + right: URLPattern, +) { + const options = component === "hostname" + ? HOSTNAME_OPTIONS + : component === "pathname" + ? PATHNAME_OPTIONS + : DEFAULT_OPTIONS; + const left_parts = parse_a_pattern_string(left[component], options, identity); + const right_parts = parse_a_pattern_string( + right[component], + options, + identity, + ); + const length = Math.min(left_parts.length, right_parts.length) + 1; + + for (let index = 0; index < length; index++) { + return compare_part(left_parts[index], right_parts[index]); + } + + return 0; +} + +function identity(value: Type): Type { + return value; +} + +function compare_part(left: Part = FINAL_PART, right: Part = FINAL_PART) { + const type_specificity = TYPE_SPECIFICITY[left.type] - + TYPE_SPECIFICITY[right.type]; + if (type_specificity !== 0) return type_specificity; + + const modifier_specificity = MODIFIER_SPECIFICITY[left.modifier] - + MODIFIER_SPECIFICITY[right.modifier]; + if (modifier_specificity !== 0) return modifier_specificity; + + return (left.prefix + left.value + left.suffix).localeCompare( + right.prefix + right.value + right.suffix, + "en", + ); +}