1
1
<script setup lang="ts">
2
2
import { useCopy } from ' @/composable/copy' ;
3
+ import { useQueryParamOrStorage } from ' @/composable/queryParams' ;
3
4
import { useValidation } from ' @/composable/validation' ;
4
5
import { isNotThrowing } from ' @/utils/boolean' ;
5
6
import { withDefaultOnError } from ' @/utils/defaults' ;
6
7
8
+ const encodings = [
9
+ { value: ' URIComponent' , label: ' URIComponent' },
10
+ { value: ' RFC3986URIComponent' , label: ' RFC3986 - URIComponent' },
11
+ { value: ' RFC5987' , label: ' RFC5987 (Link - Content-Disposition)' },
12
+ { value: ' URI' , label: ' URI' },
13
+ { value: ' RFC3986URI' , label: ' RFC3986 - URI' },
14
+ ];
15
+ const encoding = useQueryParamOrStorage ({ name: ' enc' , storageName: ' url-encode:enc' , defaultValue: ' URIComponent' });
16
+
17
+ function encodeRFC3986URIComponent(str : string ) {
18
+ return encodeURIComponent (str ).replace (
19
+ / [!'()*] / g ,
20
+ (c : string ) => ` %${c .charCodeAt (0 ).toString (16 ).toUpperCase ()} ` ,
21
+ );
22
+ }
23
+
24
+ function encodeRFC5987ValueChars(str : string ) {
25
+ return (
26
+ encodeURIComponent (str )
27
+ // The following creates the sequences %27 %28 %29 %2A (Note that
28
+ // the valid encoding of "*" is %2A, which necessitates calling
29
+ // toUpperCase() to properly encode). Although RFC3986 reserves "!",
30
+ // RFC5987 does not, so we do not need to escape it.
31
+ .replace (
32
+ / ['()*] / g ,
33
+ c => ` %${c .charCodeAt (0 ).toString (16 ).toUpperCase ()} ` ,
34
+ )
35
+ // The following are not required for percent-encoding per RFC5987,
36
+ // so we can allow for a little better readability over the wire: |`^
37
+ .replace (/ %(7C| 60| 5E)/ g , (str , hex ) =>
38
+ String .fromCharCode (Number .parseInt (hex , 16 )),
39
+ )
40
+ );
41
+ }
42
+
43
+ function encodeRFC3986URI(str : string ) {
44
+ return encodeURI (str )
45
+ .replace (/ %5B/ g , ' [' )
46
+ .replace (/ %5D/ g , ' ]' )
47
+ .replace (
48
+ / [!'()*] / g ,
49
+ c => ` %${c .charCodeAt (0 ).toString (16 ).toUpperCase ()} ` ,
50
+ );
51
+ }
52
+
53
+ function encode(str : string ) {
54
+ if (encoding .value === ' URIComponent' ) {
55
+ return encodeURIComponent (str );
56
+ }
57
+ if (encoding .value === ' RFC3986URIComponent' ) {
58
+ return encodeRFC3986URIComponent (str );
59
+ }
60
+ if (encoding .value === ' RFC5987' ) {
61
+ return encodeRFC5987ValueChars (str );
62
+ }
63
+ if (encoding .value === ' URI' ) {
64
+ return encodeURI (str );
65
+ }
66
+ if (encoding .value === ' RFC3986URI' ) {
67
+ return encodeRFC3986URI (str );
68
+ }
69
+ return str ;
70
+ }
71
+
7
72
const encodeInput = ref (' Hello world :)' );
8
- const encodeOutput = computed (() => withDefaultOnError (() => encodeURIComponent (encodeInput .value ), ' ' ));
73
+ const encodeOutput = computed (() => withDefaultOnError (() => encode (encodeInput .value ), ' ' ));
9
74
10
75
const encodedValidation = useValidation ({
11
76
source: encodeInput ,
12
77
rules: [
13
78
{
14
- validator : value => isNotThrowing (() => encodeURIComponent (value )),
79
+ validator : value => isNotThrowing (() => encode (value )),
15
80
message: ' Impossible to parse this string' ,
16
81
},
17
82
],
@@ -23,7 +88,7 @@ const decodeInput = ref('Hello%20world%20%3A)');
23
88
const decodeOutput = computed (() => withDefaultOnError (() => decodeURIComponent (decodeInput .value ), ' ' ));
24
89
25
90
const decodeValidation = useValidation ({
26
- source: decodeInput ,
91
+ source: encodeInput ,
27
92
rules: [
28
93
{
29
94
validator : value => isNotThrowing (() => decodeURIComponent (value )),
@@ -37,6 +102,15 @@ const { copy: copyDecoded } = useCopy({ source: decodeOutput, text: 'Decoded str
37
102
38
103
<template >
39
104
<c-card title =" Encode" >
105
+ <c-select
106
+ v-model:value =" encoding"
107
+ label =" Encoding Kind:"
108
+ label-position =" left"
109
+ :options =" encodings"
110
+ />
111
+
112
+ <n-divider />
113
+
40
114
<c-input-text
41
115
v-model:value =" encodeInput"
42
116
label =" Your string :"
0 commit comments