barefoot_js 0.39.8 → 0.39.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/barefoot_js.rb +67 -5
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca01f4cd2478ff3996932ab0ea7102c799e74c2602f63313ca3ea6ed1e3e7ef7
|
|
4
|
+
data.tar.gz: 546f0e92374f3947eae8965b2771a3ba6928526eddaa8b9f1e3ced6883deed1f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: de992621414ebaf15ae3237dc62c1190bab959f516ed0047026af8a64a1dc87db978d8d43c86e30278f3087c6e45953ff676c9ffb486d8499dc3eb010586cfa5
|
|
7
|
+
data.tar.gz: dc2aa7213b1e63646a13f0c9340377731ab62baf7731ffcbed0bb517a78ff79d866f08a3a7c985990f666f01532a79237be42c346791d7bff213fa1e83f3a5c6
|
data/lib/barefoot_js.rb
CHANGED
|
@@ -1034,18 +1034,28 @@ module BarefootJS
|
|
|
1034
1034
|
end
|
|
1035
1035
|
|
|
1036
1036
|
# `Array.prototype.indexOf(x)` / `.lastIndexOf(x)` -- value-equality
|
|
1037
|
-
# search.
|
|
1037
|
+
# search. A String receiver is `String.prototype.indexOf`, counted in
|
|
1038
|
+
# UTF-16 code units like JS (#3613). Other receivers return -1.
|
|
1038
1039
|
def index_of(recv, elem)
|
|
1040
|
+
return utf16_index_of(recv, elem, false) if recv.is_a?(String)
|
|
1041
|
+
|
|
1039
1042
|
array_index_of(recv, elem, false)
|
|
1040
1043
|
end
|
|
1041
1044
|
|
|
1042
1045
|
def last_index_of(recv, elem)
|
|
1046
|
+
return utf16_index_of(recv, elem, true) if recv.is_a?(String)
|
|
1047
|
+
|
|
1043
1048
|
array_index_of(recv, elem, true)
|
|
1044
1049
|
end
|
|
1045
1050
|
|
|
1046
1051
|
# `Array.prototype.at(i)` -- negative indices count from the end;
|
|
1047
1052
|
# out-of-bounds -> nil (renders as '' via `h`, matching JS `undefined`).
|
|
1053
|
+
# A String receiver is indexed in UTF-16 code units (#3613). Half of a
|
|
1054
|
+
# surrogate pair, a lone surrogate in JS, comes back as U+FFFD: a
|
|
1055
|
+
# UTF-8 Ruby String can't hold one, so the halves compare equal and
|
|
1056
|
+
# don't rejoin (limitation `string-at-lone-surrogate`).
|
|
1048
1057
|
def at(recv, i)
|
|
1058
|
+
return utf16_at(recv, i) if recv.is_a?(String)
|
|
1049
1059
|
return nil unless recv.is_a?(Array)
|
|
1050
1060
|
return nil if i.nil?
|
|
1051
1061
|
|
|
@@ -1237,9 +1247,10 @@ module BarefootJS
|
|
|
1237
1247
|
def starts_with(recv, prefix, position = nil)
|
|
1238
1248
|
s = recv.nil? ? '' : string(recv)
|
|
1239
1249
|
p = prefix.nil? ? '' : string(prefix)
|
|
1250
|
+
# `position` counts UTF-16 code units, like JS (#3613).
|
|
1240
1251
|
unless position.nil?
|
|
1241
|
-
|
|
1242
|
-
|
|
1252
|
+
units = utf16_units(s)
|
|
1253
|
+
return utf16_has_at?(units, utf16_units(p), clamp_index(to_integer_or_infinity(position), units.length))
|
|
1243
1254
|
end
|
|
1244
1255
|
s.start_with?(p)
|
|
1245
1256
|
end
|
|
@@ -1248,9 +1259,11 @@ module BarefootJS
|
|
|
1248
1259
|
def ends_with(recv, suffix, end_position = nil)
|
|
1249
1260
|
s = recv.nil? ? '' : string(recv)
|
|
1250
1261
|
x = suffix.nil? ? '' : string(suffix)
|
|
1262
|
+
# `endPosition` counts UTF-16 code units, like JS (#3613).
|
|
1251
1263
|
unless end_position.nil?
|
|
1252
|
-
|
|
1253
|
-
|
|
1264
|
+
units = utf16_units(s)
|
|
1265
|
+
needle = utf16_units(x)
|
|
1266
|
+
return utf16_has_at?(units, needle, clamp_index(to_integer_or_infinity(end_position), units.length) - needle.length)
|
|
1254
1267
|
end
|
|
1255
1268
|
s.end_with?(x)
|
|
1256
1269
|
end
|
|
@@ -1706,6 +1719,55 @@ module BarefootJS
|
|
|
1706
1719
|
-1
|
|
1707
1720
|
end
|
|
1708
1721
|
|
|
1722
|
+
# `s` as JS sees it: an Array of UTF-16 code units. JS string positions
|
|
1723
|
+
# (`indexOf`, `at`, `startsWith`'s position, ...) count these, so an
|
|
1724
|
+
# astral character such as '😀' is two units (#3613).
|
|
1725
|
+
def utf16_units(s)
|
|
1726
|
+
s.to_s.encode('UTF-16LE', invalid: :replace, undef: :replace).unpack('v*')
|
|
1727
|
+
end
|
|
1728
|
+
|
|
1729
|
+
MAX_SAFE_INDEX = 2**53
|
|
1730
|
+
|
|
1731
|
+
# JS `ToIntegerOrInfinity` for a string position or index (#3613): NaN
|
|
1732
|
+
# -> 0, truncation toward zero, and +/-Infinity clamped to +/-2**53 so
|
|
1733
|
+
# the caller's range check treats it as out of range instead of
|
|
1734
|
+
# `Float#to_i` raising FloatDomainError.
|
|
1735
|
+
def to_integer_or_infinity(value)
|
|
1736
|
+
n = number(value)
|
|
1737
|
+
return 0 if n.respond_to?(:nan?) && n.nan?
|
|
1738
|
+
return MAX_SAFE_INDEX if n >= MAX_SAFE_INDEX
|
|
1739
|
+
return -MAX_SAFE_INDEX if n <= -MAX_SAFE_INDEX
|
|
1740
|
+
|
|
1741
|
+
n.to_i
|
|
1742
|
+
end
|
|
1743
|
+
|
|
1744
|
+
def utf16_has_at?(hay, needle, at)
|
|
1745
|
+
return false if at.negative? || at + needle.length > hay.length
|
|
1746
|
+
|
|
1747
|
+
hay[at, needle.length] == needle
|
|
1748
|
+
end
|
|
1749
|
+
|
|
1750
|
+
def utf16_index_of(recv, elem, reverse)
|
|
1751
|
+
hay = utf16_units(recv)
|
|
1752
|
+
needle = utf16_units(string(elem))
|
|
1753
|
+
last = hay.length - needle.length
|
|
1754
|
+
indices = reverse ? last.downto(0) : 0.upto(last)
|
|
1755
|
+
indices.each { |i| return i if utf16_has_at?(hay, needle, i) }
|
|
1756
|
+
-1
|
|
1757
|
+
end
|
|
1758
|
+
|
|
1759
|
+
def utf16_at(recv, i)
|
|
1760
|
+
return nil if i.nil?
|
|
1761
|
+
|
|
1762
|
+
units = utf16_units(recv)
|
|
1763
|
+
idx = to_integer_or_infinity(i)
|
|
1764
|
+
idx += units.length if idx.negative?
|
|
1765
|
+
return nil if idx.negative? || idx >= units.length
|
|
1766
|
+
|
|
1767
|
+
u = units[idx]
|
|
1768
|
+
(0xD800..0xDFFF).cover?(u) ? "\uFFFD" : [u].pack('U')
|
|
1769
|
+
end
|
|
1770
|
+
|
|
1709
1771
|
def clamp_index(n, len)
|
|
1710
1772
|
n = 0 if n.negative?
|
|
1711
1773
|
n = len if n > len
|