char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
bf382b3
main
1import { 2ObjectCreate , 3ObjectDefineProperty , 4TypeError , 5WeakMapPrototypeSet as weakSet , 6} from "ext:core/primordials" ; 7import { required , state , usv } from "ext:web/idl.js" ; 8import { op_url_parse , op_url_set } from "ext:core/ops" ; 9import { URLSearchParams } from "./search_params.js" ; 10import { params , queryList , urls } from "./state.js" ; 11import type { URLComponent , URLParts } from "ext:core/ops" ; 12 13function parse ( rawInput :unknown , rawBase :unknown , count :number ) :URLParts | null { 14required ( count , 1 ); 15const input = usv ( rawInput ); 16const base = rawBase === undefined ?null :usv ( rawBase ); 17return op_url_parse ([ input , base ]); 18} 19function initializeURL ( receiver :URL , parts :URLParts ) :URL { 20const searchParams :URLSearchParams = ObjectCreate ( URLSearchParams . prototype ); 21const url = { parts, searchParams}; 22weakSet ( params , searchParams , { list :queryList ( parts ), url}); 23weakSet ( urls , receiver , url ); 24return receiver ; 25} 26// Component accessors are installed from the table below, without instance fields. 27interface URL extends Record < URLComponent , string > { 28readonly origin :string ; 29} 30class URL { 31constructor ( input :unknown , base :unknown = undefined ) { 32const parts = parse ( input , base , arguments . length ); 33if ( parts === null ) throw new TypeError ( "Invalid URL" ); 34initializeURL ( this , parts ); 35} 36static canParse ( input :unknown , base :unknown = undefined ) :boolean { 37return parse ( input , base , arguments . length ) !== null ; 38} 39static parse ( input :unknown , base :unknown = undefined ) :URL | null { 40const parts = parse ( input , base , arguments . length ); 41return parts === null 42 ?null 43 :initializeURL ( ObjectCreate ( URL . prototype ), parts ); 44} 45get searchParams () :URLSearchParams { 46return state ( urls , this ). searchParams ; 47} 48toString () :string { 49return state ( urls , this ). parts [ 0 ]; 50} 51toJSON () :string { 52return state ( urls , this ). parts [ 0 ]; 53} 54} 55const components = [ 56"href" , 57"origin" , 58"protocol" , 59"username" , 60"password" , 61"host" , 62"hostname" , 63"port" , 64"pathname" , 65"search" , 66"hash" , 67] as const ; 68for ( let index = 0 ; index < components . length ; index ++ ) { 69const name = components [ index ]; 70const descriptor :{ 71get ( this :URL ) :string ; 72set ?:( this :URL , value :unknown ) => void ; 73enumerable :boolean ; 74configurable :boolean ; 75} = { 76get ( this :URL ) { 77return state ( urls , this ). parts [ index ]; 78}, 79enumerable :true , 80configurable :true , 81}; 82if ( name !== "origin" ) { 83descriptor . set = { 84set ( this :URL , rawValue :unknown ) { 85const data = state ( urls , this ); 86const value = usv ( rawValue ); 87const parts = op_url_set ([ data . parts [ 0 ], name , value ]); 88if ( parts === null ) throw new TypeError ( "Invalid URL" ); 89data . parts = parts ; 90if ( name === "href" || name === "search" ) { 91state ( params , data . searchParams ). list = queryList ( parts ); 92} 93}, 94}. set ; 95} 96ObjectDefineProperty ( descriptor . get , "name" , { 97value :`get ${ name } ` , 98configurable :true , 99}); 100if ( descriptor . set ) { 101ObjectDefineProperty ( descriptor . set , "name" , { 102value :`set ${ name } ` , 103configurable :true , 104}); 105} 106ObjectDefineProperty ( URL . prototype , name , descriptor ); 107} 108 109export { URL };