├── .gitignore ├── .htaccess ├── Makefile ├── README.md ├── liveview.html ├── liveview2.html ├── liveview3.html ├── style.css ├── uri-validate.html ├── uri-validate.js └── url.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | Options +Indexes 2 | IndexOptions +ScanHTMLTitles 3 | IndexIgnore style.css url.js uri-validate.js 4 | 5 | Redirect 301 /url/liveview1.html /url/liveview.html 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | copy: liveview.html 2 | cp liveview.html liveview2.html 3 | cp liveview.html liveview3.html 4 | 5 | build: 6 | npm i whatwg-url; echo 'window.Url = require("whatwg-url").URL;' > temp.js; browserify temp.js -o url.js 7 | rm temp.js 8 | make copy 9 | 10 | deploy: 11 | scp .htaccess *.css *.html *.js anne:quuz.org/url/ 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Setup 2 | 3 | To generate a new version of `url.js` and copy `liveview2.html` and `liveview3.html` from 4 | `liveview.html`, run `make build`. To just update `liveview2.html` and `liveview3.html`, run `make`. 5 | 6 | Fixing https://github.com/jsdom/whatwg-url/issues/61 can help make uri-validate.html functional 7 | again and provide more detailed feedback in liveview too. 8 | 9 | ## Acknowledgments 10 | 11 | * Sam Ruby 12 | * Sebastian Mayr 13 | -------------------------------------------------------------------------------- /liveview.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | Live URL Viewer 4 | 5 | 6 | 7 |

Live URL Viewer

8 | 9 |

The output below will display a URL's parsed components from the browser and from 10 | jsdom/whatwg-url for the 11 | URL Standard. The output will be colored 12 | dark green unless a difference occurs between the two parsers in which 13 | case the affected URL component will be colored red. 14 | 15 |

16 | 17 | 18 | 19 |
20 |

21 | 22 |
23 | 24 |
25 | 26 | 38 | 39 | 40 |
41 | 42 |

Browser's URL components

43 | 44 |
45 |
46 | href 47 | 48 |
49 |
50 | protocol 51 | 52 |
53 |
54 | username 55 | 56 |
57 |
58 | password 59 | 60 |
61 |
62 | port 63 | 64 |
65 |
66 | hostname 67 | 68 |
69 |
70 | pathname 71 | 72 |
73 |
74 | search 75 | 76 |
77 |
78 | hash 79 | 80 |
81 |
82 | error 83 | 84 |
85 |
86 | 87 |

jsdom/whatwg-url's URL components

88 | 89 |
90 |
91 | href 92 | 93 |
94 |
95 | protocol 96 | 97 |
98 |
99 | username 100 | 101 |
102 |
103 | password 104 | 105 |
106 |
107 | hostname 108 | 109 |
110 |
111 | port 112 | 113 |
114 |
115 | pathname 116 | 117 |
118 |
119 | search 120 | 121 |
122 |
123 | hash 124 | 125 |
126 |
127 | error 128 | 129 |
130 |
131 | 132 | 133 | 134 | 327 | -------------------------------------------------------------------------------- /liveview2.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | Live URL Viewer 4 | 5 | 6 | 7 |

Live URL Viewer

8 | 9 |

The output below will display a URL's parsed components from the browser and from 10 | jsdom/whatwg-url for the 11 | URL Standard. The output will be colored 12 | dark green unless a difference occurs between the two parsers in which 13 | case the affected URL component will be colored red. 14 | 15 |

16 | 17 | 18 | 19 |
20 |

21 | 22 |
23 | 24 |
25 | 26 | 38 | 39 | 40 |
41 | 42 |

Browser's URL components

43 | 44 |
45 |
46 | href 47 | 48 |
49 |
50 | protocol 51 | 52 |
53 |
54 | username 55 | 56 |
57 |
58 | password 59 | 60 |
61 |
62 | port 63 | 64 |
65 |
66 | hostname 67 | 68 |
69 |
70 | pathname 71 | 72 |
73 |
74 | search 75 | 76 |
77 |
78 | hash 79 | 80 |
81 |
82 | error 83 | 84 |
85 |
86 | 87 |

jsdom/whatwg-url's URL components

88 | 89 |
90 |
91 | href 92 | 93 |
94 |
95 | protocol 96 | 97 |
98 |
99 | username 100 | 101 |
102 |
103 | password 104 | 105 |
106 |
107 | hostname 108 | 109 |
110 |
111 | port 112 | 113 |
114 |
115 | pathname 116 | 117 |
118 |
119 | search 120 | 121 |
122 |
123 | hash 124 | 125 |
126 |
127 | error 128 | 129 |
130 |
131 | 132 | 133 | 134 | 327 | -------------------------------------------------------------------------------- /liveview3.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | Live URL Viewer 4 | 5 | 6 | 7 |

Live URL Viewer

8 | 9 |

The output below will display a URL's parsed components from the browser and from 10 | jsdom/whatwg-url for the 11 | URL Standard. The output will be colored 12 | dark green unless a difference occurs between the two parsers in which 13 | case the affected URL component will be colored red. 14 | 15 |

16 | 17 | 18 | 19 |
20 |

21 | 22 |
23 | 24 |
25 | 26 | 38 | 39 | 40 |
41 | 42 |

Browser's URL components

43 | 44 |
45 |
46 | href 47 | 48 |
49 |
50 | protocol 51 | 52 |
53 |
54 | username 55 | 56 |
57 |
58 | password 59 | 60 |
61 |
62 | port 63 | 64 |
65 |
66 | hostname 67 | 68 |
69 |
70 | pathname 71 | 72 |
73 |
74 | search 75 | 76 |
77 |
78 | hash 79 | 80 |
81 |
82 | error 83 | 84 |
85 |
86 | 87 |

jsdom/whatwg-url's URL components

88 | 89 |
90 |
91 | href 92 | 93 |
94 |
95 | protocol 96 | 97 |
98 |
99 | username 100 | 101 |
102 |
103 | password 104 | 105 |
106 |
107 | hostname 108 | 109 |
110 |
111 | port 112 | 113 |
114 |
115 | pathname 116 | 117 |
118 |
119 | search 120 | 121 |
122 |
123 | hash 124 | 125 |
126 |
127 | error 128 | 129 |
130 |
131 | 132 | 133 | 134 | 327 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | 2 | * { 3 | margin: 2px; 4 | padding: 2px; 5 | font-family: Georgia; 6 | } 7 | 8 | body { max-width:70em; } 9 | 10 | h1, h2, h3, h4, h5, h6 { 11 | font-style: italic; 12 | color: DarkBlue; 13 | margin-bottom: 0.2em; 14 | margin-top: 0.2em; 15 | } 16 | 17 | h2 { 18 | font-size: 1.5em; 19 | font-weight: bold; 20 | } 21 | 22 | p { 23 | margin-top: 0.5em; 24 | word-spacing: 0.3ex; 25 | display: block; 26 | } 27 | 28 | footer { 29 | position:absolute; 30 | top:1em; 31 | right:1em; 32 | } 33 | 34 | .input { 35 | width: 90%; 36 | margin: 10px; 37 | } 38 | 39 | .result { 40 | font-family: 'Bitstream Vera Sans Mono', 'Andale Mono', 'Lucida Console', monospace, fixed; 41 | } 42 | 43 | .pass { 44 | font-family: 'Bitstream Vera Sans Mono', 'Andale Mono', 'Lucida Console', monospace, fixed; 45 | color: green; 46 | } 47 | 48 | 49 | .title { 50 | width: 100px; 51 | display: inline-block; 52 | } 53 | 54 | .title:after { 55 | content: ":"; 56 | } 57 | 58 | .fail { 59 | font-family: 'Bitstream Vera Sans Mono', 'Andale Mono', 'Lucida Console', monospace, fixed; 60 | color: red; 61 | } 62 | 63 | .output { 64 | background-color: whitesmoke; 65 | border: 1px dashed crimson; 66 | width: 95%; 67 | float: none; 68 | padding: 1em; 69 | } 70 | 71 | #domException, #urlException { 72 | color: Crimson; 73 | } 74 | 75 | #value { 76 | display: inline; 77 | width: 60%; 78 | } 79 | -------------------------------------------------------------------------------- /uri-validate.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | URI/URL validator 4 | 5 | 6 | 9 | 10 |

URI/URL validator

11 | 12 | 13 |

14 | Valid URI reference: 15 | 16 |

17 | 18 |

19 | Valid URL: 20 | 21 |

22 | 23 | 24 | 25 | 61 | -------------------------------------------------------------------------------- /uri-validate.js: -------------------------------------------------------------------------------- 1 | /* 2 | Regex for URIs 3 | 4 | These regex are directly derived from the collected ABNF in RFC3986 5 | (except for DIGIT, ALPHA and HEXDIG, defined by RFC2234). 6 | 7 | Additional regex are defined to validate the following schemes according to 8 | their respective specifications: 9 | - http 10 | - https 11 | - file 12 | - data 13 | - gopher 14 | - ws 15 | - wss 16 | - mailto 17 | 18 | See FIXME for areas that still need work. 19 | 20 | JavaScript translation of https://gist.github.com/mnot/138549 21 | 22 | Copyright (c) 2009-2015 Mark Nottingham (code portions) 23 | 24 | Permission is hereby granted, free of charge, to any person obtaining a copy 25 | of this software and associated documentation files (the "Software"), to deal 26 | in the Software without restriction, including without limitation the rights 27 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | copies of the Software, and to permit persons to whom the Software is 29 | furnished to do so, subject to the following conditions: 30 | 31 | The above copyright notice and this permission notice shall be included in 32 | all copies or substantial portions of the Software. 33 | 34 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 37 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 39 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 40 | THE SOFTWARE. 41 | */ 42 | 43 | //// basics - 44 | 45 | var DIGIT = "[0-9]"; 46 | var ALPHA = "[A-Za-z]"; 47 | var HEXDIG = "[0-9A-Fa-f]"; 48 | var DQUOTE = "\""; 49 | 50 | // pct-encoded = "%" HEXDIG HEXDIG 51 | var pct_encoded = "%%" + HEXDIG + HEXDIG; 52 | 53 | // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 54 | var unreserved = "(?:" + ALPHA + "|" + DIGIT + "|\\-|\\.|_|~)"; 55 | 56 | // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" 57 | var gen_delims = "(?::|/|\\?|#|\\[|\\]|@)"; 58 | 59 | // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" 60 | // / "*" / "+" / "," / ";" / "=" 61 | var sub_delims = "(?:!|\\$|&|'|\\(|\\)|\\*|\\+|,|;|=)"; 62 | 63 | // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" 64 | var pchar = "(?:" + unreserved + "|" + pct_encoded + "|" + sub_delims + "|:|@)"; 65 | 66 | // reserved = gen-delims / sub-delims 67 | var reserved = "(?:" + gen_delims + "|" + sub_delims + ")"; 68 | 69 | 70 | //// scheme 71 | 72 | // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 73 | var scheme = ALPHA + "(?:" + ALPHA + "|" + DIGIT + "|\\+|\\-|\\.)*"; 74 | 75 | 76 | //// authority 77 | 78 | // dec-octet = DIGIT ; 0-9 79 | // / %x31-39 DIGIT ; 10-99 80 | // / "1" 2DIGIT ; 100-199 81 | // / "2" %x30-34 DIGIT ; 200-249 82 | // / "25" %x30-35 ; 250-255 83 | var dec_octet = "(?:" + DIGIT + "|[1-9]" + DIGIT + "|1" + DIGIT + "{2}|2[0-4]" + 84 | DIGIT + "|25[0-5])"; 85 | 86 | // IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet 87 | var IPv4address = dec_octet + "\\." + dec_octet + "\\." + dec_octet + "\\." + 88 | dec_octet; 89 | 90 | // h16 = 1*4HEXDIG 91 | var h16 = "(?:" + HEXDIG + "){1,4}"; 92 | 93 | // ls32 = ( h16 ":" h16 ) / IPv4address 94 | var ls32 = "(?:(?:" + h16 + ":" + h16 + ")|" + IPv4address + ")"; 95 | 96 | // IPv6address = 6( h16 ":" ) ls32 97 | // / "::" 5( h16 ":" ) ls32 98 | // / [ h16 ] "::" 4( h16 ":" ) ls32 99 | // / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 100 | // / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 101 | // / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 102 | // / [ *4( h16 ":" ) h16 ] "::" ls32 103 | // / [ *5( h16 ":" ) h16 ] "::" h16 104 | // / [ *6( h16 ":" ) h16 ] "::" 105 | var IPv6address = "(?:(?:" + h16 + ":){6}" + ls32 + "|::(?:" + h16 + ":){5}" + 106 | ls32 + "|(?:" + h16 + ")?::(?:" + h16 + ":){4}" + ls32 + "|(?:(?:" + h16 + 107 | ":){0,1}" + h16 + ")?::(?:" + h16 + ":){3}" + ls32 + "|(?:(?:" + h16 + 108 | ":){0,2}" + h16 + ")?::(?:" + h16 + ":){2}" + ls32 + "|(?:(?:" + h16 + 109 | ":){0,3}" + h16 + ")?::" + h16 + ":" + ls32 + "|(?:(?:" + h16 + ":){0,4}" + 110 | h16 + ")?::" + ls32 + "|(?:(?:" + h16 + ":){0,5}" + h16 + ")?::" + h16 + 111 | "|(?:(?:" + h16 + ":){0,6}" + h16 + ")?::)"; 112 | 113 | // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) 114 | var IPvFuture = "v" + HEXDIG + "+\\.(?:" + unreserved + "|" + sub_delims + 115 | "|:)+"; 116 | 117 | // IP-literal = "[" ( IPv6address / IPvFuture ) "]" 118 | var IP_literal = "\\[(?:" + IPv6address + "|" + IPvFuture + ")\\]"; 119 | 120 | // reg-name = *( unreserved / pct-encoded / sub-delims ) 121 | var reg_name = "(?:" + unreserved + "|" + pct_encoded + "|" + sub_delims + ")*"; 122 | 123 | // userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 124 | var userinfo = "(?:" + unreserved + "|" + pct_encoded + "|" + sub_delims + 125 | "|:)*"; 126 | 127 | // host = IP-literal / IPv4address / reg-name 128 | var host = "(?:" + IP_literal + "|" + IPv4address + "|" + reg_name + ")"; 129 | 130 | // port = *DIGIT 131 | var port = "(?:" + DIGIT + ")*"; 132 | 133 | // authority = [ userinfo "@" ] host [ ":" port ] 134 | var authority = "(?:" + userinfo + "@)?" + host + "(?::" + port + ")?"; 135 | 136 | 137 | 138 | //// Path 139 | 140 | // segment = *pchar 141 | var segment = pchar + "*"; 142 | 143 | // segment-nz = 1*pchar 144 | var segment_nz = pchar + "+"; 145 | 146 | // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) 147 | // ; non-zero-length segment without any colon ":" 148 | var segment_nz_nc = "(?:" + unreserved + "|" + pct_encoded + "|" + sub_delims + 149 | "|@)+"; 150 | 151 | // path-abempty = *( "/" segment ) 152 | var path_abempty = "(?:/" + segment + ")*"; 153 | 154 | // path-absolute = "/" [ segment-nz *( "/" segment ) ] 155 | var path_absolute = "/(?:" + segment_nz + "(?:/" + segment + ")*)?"; 156 | 157 | // path-noscheme = segment-nz-nc *( "/" segment ) 158 | var path_noscheme = segment_nz_nc + "(?:/" + segment + ")*"; 159 | 160 | // path-rootless = segment-nz *( "/" segment ) 161 | var path_rootless = segment_nz + "(?:/" + segment + ")*"; 162 | 163 | // path-empty = 0 164 | var path_empty = ""; 165 | 166 | // path = path-abempty ; begins with "/" or is empty 167 | // / path-absolute ; begins with "/" but not "//" 168 | // / path-noscheme ; begins with a non-colon segment 169 | // / path-rootless ; begins with a segment 170 | // / path-empty ; zero characters 171 | var path = "(?:" + path_abempty + "|" + path_absolute + "|" + path_noscheme + 172 | "|" + path_rootless + "|" + path_empty + ")"; 173 | 174 | 175 | 176 | //// Query and Fragment 177 | 178 | // query = *( pchar / "/" / "?" ) 179 | var query = "(?:" + pchar + "|/|\\?)*"; 180 | 181 | // fragment = *( pchar / "/" / "?" ) 182 | var fragment = "(?:" + pchar + "|/|\\?)*"; 183 | 184 | 185 | 186 | //// URIs 187 | 188 | // hier-part = "//" authority path-abempty 189 | // / path-absolute 190 | // / path-rootless 191 | // / path-empty 192 | var hier_part = "(?:(?://" + authority + path_abempty + ")|" + path_absolute + 193 | "|" + path_rootless + "|" + path_empty + ")"; 194 | 195 | // relative-part = "//" authority path-abempty 196 | // / path-absolute 197 | // / path-noscheme 198 | // / path-empty 199 | var relative_part = "(?:(?://" + authority + path_abempty + ")|" + 200 | path_absolute + "|" + path_noscheme + "|" + path_empty + ")"; 201 | 202 | // relative-ref = relative-part [ "?" query ] [ "#" fragment ] 203 | var relative_ref = relative_part + "(?:\\?" + query + ")?(?:#" + fragment + 204 | ")?"; 205 | 206 | // URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 207 | var URI = "(?:" + scheme + ":" + hier_part + "(?:\\?" + query + ")?(?:#" + 208 | fragment + ")?)"; 209 | 210 | // URI-reference = URI / relative-ref 211 | var URI_reference = "(?:" + URI + "|" + relative_ref + ")"; 212 | 213 | // absolute-URI = scheme ":" hier-part [ "?" query ] 214 | var absolute_URI = "(?:" + scheme + ":" + hier_part + "(?:\\?" + query + ")?)"; 215 | 216 | 217 | 218 | //// HTTP[S] - RFC7230 219 | 220 | // http-URI = "http:" "//" authority path-abempty [ "?" query ] 221 | // [ "#" fragment ] 222 | 223 | var http_URI = "(?:http://" + authority + path_abempty + "(?:\\?" + query + 224 | ")?(?:#" + fragment + ")?)"; 225 | 226 | // https-URI = "https:" "//" authority path-abempty [ "?" query ] 227 | // [ "#" fragment ] 228 | 229 | var https_URI = "(?:https://" + authority + path_abempty + "(?:\\?" + query + 230 | ")?(?:#" + fragment + ")?)"; 231 | 232 | 233 | 234 | //// WS[S] - RFC6455 235 | 236 | // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ] 237 | 238 | var ws_URI = "(?:ws://" + host + "(?::" + port + ")?" + path + "(?:\\?" + 239 | query + ")?)"; 240 | 241 | // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ] 242 | 243 | var wss_URI = "(?:wss://" + host + "(?::" + port + ")?" + path + "(?:\\?" + 244 | query + ")?)"; 245 | 246 | 247 | 248 | //// mailto - RFC6068 249 | 250 | // some-delims = "!" / "$" / "'" / "(" / ")" / "*" 251 | // / "+" / "," / ";" / ":" / "@" 252 | 253 | var some_delims = "(?:!|\\$|'|\\(|\\)|\\*\\+|,|;|:|@)"; 254 | 255 | // qchar = unreserved / pct-encoded / some-delims 256 | 257 | var qchar = "(?:" + unreserved + "|" + pct_encoded + "|" + some_delims + ")"; 258 | 259 | // dtext-no-obs = %d33-90 / ; Printable US-ASCII 260 | // %d94-126 ; characters not including 261 | // ; "[", "]", or "\" 262 | 263 | var dtext_no_obs = "(?:[!-[^-~])"; 264 | 265 | // atext = ALPHA / DIGIT / ; Printable US-ASCII 266 | // "!" / "#" / ; characters not including 267 | // "$" / "%" / ; specials. Used for atoms. 268 | // "&" / "'" / 269 | // "*" / "+" / 270 | // "-" / "/" / 271 | // "=" / "?" / 272 | // "^" / "_" / 273 | // "`" / "{" / 274 | // "|" / "}" / 275 | // "~" 276 | // 277 | // dot-atom-text = 1*atext *("." 1*atext) 278 | 279 | var rfc5322_atext = "(?:" + ALPHA + "|" + DIGIT + 280 | "|!|#|\\$|%%|&|'|\\*|\\+|-|/|=|\\?|\\^|_|`|{|\\||}|~)"; 281 | var rfc5322_dot_atom_text = "(?:" + rfc5322_atext + "{1,}(?:." + rfc5322_atext + 282 | "{1,})*)"; 283 | var qcontent; 284 | var rfc5322_FWS; 285 | var rfc5322_CFWS; 286 | qcontent = rfc5322_FWS = rfc5322_CFWS = "(?:)"; 287 | 288 | // quoted-string = [CFWS] 289 | // DQUOTE *([FWS] qcontent) [FWS] DQUOTE 290 | // [CFWS] 291 | 292 | var rfc5322_quoted_string = "(?:(?:" + rfc5322_CFWS + ")?" + DQUOTE + "(?:(?:" + 293 | rfc5322_FWS + ")?" + qcontent + ")*(?:" + rfc5322_FWS + ")?" + DQUOTE + 294 | "(?:" + rfc5322_CFWS + ")?)"; 295 | 296 | // domain = dot-atom-text / "[" *dtext-no-obs "]" 297 | 298 | var domain = "(?:" + rfc5322_dot_atom_text + "|(?:\\[" + dtext_no_obs + 299 | "*\\]))"; 300 | 301 | // local-part = dot-atom-text / quoted-string 302 | 303 | var local_part = "(?:" + rfc5322_dot_atom_text + "|" + rfc5322_quoted_string + 304 | ")"; 305 | 306 | // addr-spec = local-part "@" domain 307 | 308 | var addr_spec = "(?:" + local_part + "@" + domain + ")"; 309 | 310 | // hfvalue = *qchar 311 | 312 | var hfvalue = "(?:" + qchar + "*)"; 313 | 314 | // hfname = *qchar 315 | 316 | var hfname = "(?:" + qchar + "*)"; 317 | 318 | // hfield = hfname "=" hfvalue 319 | 320 | var hfield = "(?:" + hfname + "=" + hfvalue + ")"; 321 | 322 | // to = addr-spec *("," addr-spec ) 323 | 324 | var to = "(?:" + addr_spec + "(?:," + addr_spec + ")*)"; 325 | 326 | // hfields = "?" hfield *( "&" hfield ) 327 | 328 | var hfields = "(?:\\?" + hfield + "(?:&" + hfield + ")*)"; 329 | 330 | // mailtoURI = "mailto:" [ to ] [ hfields ] 331 | 332 | var mailto_URI = "(?:mailto:(?:" + to + ")?(?:" + hfields + ")?)"; 333 | 334 | 335 | //// data - RFC2397 (+ RFC2045) 336 | 337 | // ietf-token := 340 | 341 | var rfc2045_token = "(?:[0-z]+)"; 342 | var rfc2045_ietf_token = rfc2045_token; 343 | var rfc2045_iana_tokens = rfc2045_token; 344 | 345 | // x-token := 347 | 348 | var rfc2045_x_token = "(?:[xX]-" + rfc2045_token + ")"; 349 | 350 | // extension-token := ietf-token / x-token 351 | 352 | var rfc2045_extension_token = "(?:" + rfc2045_ietf_token + "|" + 353 | rfc2045_x_token + ")"; 354 | 355 | // discrete-type := "text" / "image" / "audio" / "video" / 356 | // "application" / extension-token 357 | 358 | var rfc2045_discrete_type = "(?:text|image|audio|video|application|" + 359 | rfc2045_extension_token + ")"; 360 | 361 | // composite-type := "message" / "multipart" / extension-token 362 | 363 | var rfc2045_composite_type = "(?:message|multipart|" + rfc2045_extension_token + 364 | ")"; 365 | 366 | // type := discrete-type / composite-type 367 | 368 | var rfc2045_type = "(?:" + rfc2045_discrete_type + "|" + 369 | rfc2045_composite_type + ")"; 370 | 371 | // subtype := extension-token / iana-token 372 | 373 | var rfc2045_subtype = "(?:" + rfc2045_extension_token + "|" + 374 | rfc2045_iana_tokens + ")"; 375 | 376 | // parameter := attribute "=" value 377 | // attribute := token 378 | // ; Matching of attributes 379 | // ; is ALWAYS case-insensitive. 380 | // 381 | // value := token / quoted-string 382 | 383 | var rfc2045_quoted_string = "(?:)"; 384 | var rfc2045_attribute = "(?:" + rfc2045_token + ")"; 385 | var rfc2045_value = "(?:" + rfc2045_token + "|" + rfc2045_quoted_string + ")"; 386 | var rfc2045_parameter = "(?:" + rfc2045_attribute + "=" + rfc2045_value + ")"; 387 | 388 | // mediatype := [ type "/" subtype ] *( ";" parameter ) 389 | 390 | var mediatype = "(?:(?:" + rfc2045_type + "/" + rfc2045_subtype + ")?(?:;" + 391 | rfc2045_parameter + ")*)"; 392 | 393 | // uric = reserved | unreserved | escaped // 2396 394 | // data := *urlchar 395 | 396 | var rfc2396_uric = "(?:" + reserved + "|" + unreserved + "|" + pct_encoded + 397 | ")"; 398 | var data = "(?:" + rfc2396_uric + "*)"; 399 | 400 | // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data 401 | 402 | var data_URI = "(?:data:(?:" + mediatype + ")?(?:;base64)?," + data + ")"; 403 | 404 | //// gopher - RFC4266 405 | 406 | // gopher://:/ 407 | 408 | var gopher_path = path; 409 | var gopher_URI = "(?:gopher://" + host + ":" + port + "/" + gopher_path + ")"; 410 | 411 | 412 | //// file - draft-kerwin-file-scheme-13 413 | 414 | // f-scheme = "file" 415 | 416 | var file_f_scheme = "(?:file)"; 417 | 418 | // f-auth = [ userinfo "@" ] host 419 | 420 | var file_f_auth = "(?:(?:" + userinfo + "@)?" + host + ")"; 421 | 422 | // unc-path = 2*3"/" authority path-absolute 423 | 424 | var file_unc_path = "(?:/{2,3}" + authority + path_absolute + ")"; 425 | 426 | // drive-marker = ":" / "|" 427 | 428 | var file_drive_marker = "(?::|\\|)"; 429 | 430 | // drive-letter = ALPHA [ drive-marker ] 431 | 432 | var file_drive_letter = "(?:" + ALPHA + "(?:" + file_drive_marker + ")?)"; 433 | 434 | // windows-path = drive-letter path-absolute 435 | 436 | var file_windows_path = "(?:" + file_drive_letter + path_absolute + ")"; 437 | 438 | // local-path = path-absolute 439 | // / windows-path 440 | 441 | var file_local_path = "(?:" + path_absolute + "|" + file_windows_path + ")"; 442 | 443 | // auth-path = [ f-auth ] path-absolute 444 | // / unc-path 445 | // / windows-path 446 | 447 | var file_auth_path = "(?:(?:" + file_f_auth + "?" + path_absolute + ")|" + 448 | file_unc_path + "|" + file_windows_path + ")"; 449 | 450 | // f-hier-part = "//" auth-path 451 | // / local-path 452 | 453 | var file_f_hier_part = "(?:(?://" + file_auth_path + ")|" + file_local_path + 454 | ")"; 455 | 456 | // file-URI = f-scheme ":" f-hier-part [ "?" query ] 457 | 458 | var file_URI = "(?:" + file_f_scheme + ":" + file_f_hier_part + "(?:\\?" + 459 | query + ")?)"; 460 | 461 | var known = { 462 | http: http_URI, 463 | https: https_URI, 464 | ws: ws_URI, 465 | wss: wss_URI, 466 | mailto: mailto_URI, 467 | data: data_URI, 468 | gopher: gopher_URI, 469 | file: file_URI 470 | }; 471 | 472 | function uri_validate(string) { 473 | if (!new RegExp("^" + URI_reference + "$").test(string)) { 474 | return false 475 | } else if (string.indexOf(":") == -1) { 476 | return true 477 | } else { 478 | var scheme = string.split(":")[0].toLowerCase(); 479 | if (!known[scheme]) return true; 480 | return new RegExp("^" + known[scheme] + "($|#" + fragment + ")").test(string) 481 | } 482 | } 483 | --------------------------------------------------------------------------------