You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.1 KiB
116 lines
3.1 KiB
4 years ago
|
'use strict'
|
||
|
|
||
|
var UTF8_ACCEPT = 12
|
||
|
var UTF8_REJECT = 0
|
||
|
var UTF8_DATA = [
|
||
|
// The first part of the table maps bytes to character to a transition.
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||
|
4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||
|
6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 7,
|
||
|
10, 9, 9, 9, 11, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||
|
|
||
|
// The second part of the table maps a state to a new state when adding a
|
||
|
// transition.
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
12, 0, 0, 0, 0, 24, 36, 48, 60, 72, 84, 96,
|
||
|
0, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
|
||
|
// The third part maps the current transition to a mask that needs to apply
|
||
|
// to the byte.
|
||
|
0x7F, 0x3F, 0x3F, 0x3F, 0x00, 0x1F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07
|
||
|
]
|
||
|
|
||
|
function decodeURIComponent (uri) {
|
||
|
var percentPosition = uri.indexOf('%')
|
||
|
if (percentPosition === -1) return uri
|
||
|
|
||
|
var length = uri.length
|
||
|
var decoded = ''
|
||
|
var last = 0
|
||
|
var codepoint = 0
|
||
|
var startOfOctets = percentPosition
|
||
|
var state = UTF8_ACCEPT
|
||
|
|
||
|
while (percentPosition > -1 && percentPosition < length) {
|
||
|
var high = hexCodeToInt(uri[percentPosition + 1], 4)
|
||
|
var low = hexCodeToInt(uri[percentPosition + 2], 0)
|
||
|
var byte = high | low
|
||
|
var type = UTF8_DATA[byte]
|
||
|
state = UTF8_DATA[256 + state + type]
|
||
|
codepoint = (codepoint << 6) | (byte & UTF8_DATA[364 + type])
|
||
|
|
||
|
if (state === UTF8_ACCEPT) {
|
||
|
decoded += uri.slice(last, startOfOctets)
|
||
|
|
||
|
decoded += (codepoint <= 0xFFFF)
|
||
|
? String.fromCharCode(codepoint)
|
||
|
: String.fromCharCode(
|
||
|
(0xD7C0 + (codepoint >> 10)),
|
||
|
(0xDC00 + (codepoint & 0x3FF))
|
||
|
)
|
||
|
|
||
|
codepoint = 0
|
||
|
last = percentPosition + 3
|
||
|
percentPosition = startOfOctets = uri.indexOf('%', last)
|
||
|
} else if (state === UTF8_REJECT) {
|
||
|
return null
|
||
|
} else {
|
||
|
percentPosition += 3
|
||
|
if (percentPosition < length && uri.charCodeAt(percentPosition) === 37) continue
|
||
|
return null
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return decoded + uri.slice(last)
|
||
|
}
|
||
|
|
||
|
var HEX = {
|
||
|
'0': 0,
|
||
|
'1': 1,
|
||
|
'2': 2,
|
||
|
'3': 3,
|
||
|
'4': 4,
|
||
|
'5': 5,
|
||
|
'6': 6,
|
||
|
'7': 7,
|
||
|
'8': 8,
|
||
|
'9': 9,
|
||
|
'a': 10,
|
||
|
'A': 10,
|
||
|
'b': 11,
|
||
|
'B': 11,
|
||
|
'c': 12,
|
||
|
'C': 12,
|
||
|
'd': 13,
|
||
|
'D': 13,
|
||
|
'e': 14,
|
||
|
'E': 14,
|
||
|
'f': 15,
|
||
|
'F': 15
|
||
|
}
|
||
|
|
||
|
function hexCodeToInt (c, shift) {
|
||
|
var i = HEX[c]
|
||
|
return i === undefined ? 255 : i << shift
|
||
|
}
|
||
|
|
||
|
module.exports = decodeURIComponent
|