Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Introduce JsString for encoding data to use in JavaScript #39460

Merged
merged 4 commits into from
Nov 5, 2021

Conversation

inxilpro
Copy link
Contributor

@inxilpro inxilpro commented Nov 3, 2021

I commented on #39389 but I think Taylor merged as I was commenting. This is a slight modification to the new Js object with a few benefits:

  1. In benchmarks, the current Js::from implementation is about 70% slower due to the use of atob(). It also makes the produced string much less legible in debugging (compare benchmarks for an example).
  2. This JsString implementation takes the Jsonable and Arrayable interfaces into account
  3. This enforces the JSON_HEX_TAG, JSON_HEX_APOS, JSON_HEX_AMP, and JSON_HEX_QUOT encoding flags to avoid issues with quotes and help mitigate XSS issues
  4. By using a JsString object that implements Htmlable, we can do something like {{ JsString::from($user) }} rather than needing to use the unescaped syntax {!! ... !!}
  5. I tend to think that JsString is a nice parallel to HtmlString — it's not two different concepts for two similar use cases
Show benchmarks

Benchmarks

image

You can run this benchmark on https://jsbench.me/

JsString

// Short array (20 items)
JSON.parse('[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]');

// Long array (2000 items)
JSON.parse('[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000]');

// Typical User object
JSON.parse('{\u0022id\u0022:1,\u0022given_name\u0022:\u0022Test\u0022,\u0022family_name\u0022:\u0022User\u0022,\u0022suffix\u0022:null,\u0022display_name\u0022:\u0022System\u0022,\u0022legal_name\u0022:\u0022System\u0022,\u0022username\u0022:\u0022test\u0022,\u0022role\u0022:\u0022guest\u0022,\u0022email\u0022:\u0022test@test.com\u0022,\u0022email2\u0022:null,\u0022photo\u0022:null,\u0022avatar_upload_id\u0022:null,\u0022locale\u0022:\u0022en\u0022,\u0022timezone\u0022:\u0022America\\\/New_York\u0022,\u0022latitude\u0022:null,\u0022longitude\u0022:null,\u0022confirmed\u0022:true,\u0022created_at\u0022:\u00221997-01-01 00:00:00\u0022,\u0022updated_at\u0022:\u00221997-01-01 00:00:00\u0022,\u0022account_id\u0022:1,\u0022public_id\u0022:null,\u0022aggregate_role\u0022:\u0022guest\u0022}');

Js

// Short array (20 items)
JSON.parse(atob('WzEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwXQ=='));

// Long array (2000 items)
JSON.parse(atob('WzEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLDYyLDYzLDY0LDY1LDY2LDY3LDY4LDY5LDcwLDcxLDcyLDczLDc0LDc1LDc2LDc3LDc4LDc5LDgwLDgxLDgyLDgzLDg0LDg1LDg2LDg3LDg4LDg5LDkwLDkxLDkyLDkzLDk0LDk1LDk2LDk3LDk4LDk5LDEwMCwxMDEsMTAyLDEwMywxMDQsMTA1LDEwNiwxMDcsMTA4LDEwOSwxMTAsMTExLDExMiwxMTMsMTE0LDExNSwxMTYsMTE3LDExOCwxMTksMTIwLDEyMSwxMjIsMTIzLDEyNCwxMjUsMTI2LDEyNywxMjgsMTI5LDEzMCwxMzEsMTMyLDEzMywxMzQsMTM1LDEzNiwxMzcsMTM4LDEzOSwxNDAsMTQxLDE0MiwxNDMsMTQ0LDE0NSwxNDYsMTQ3LDE0OCwxNDksMTUwLDE1MSwxNTIsMTUzLDE1NCwxNTUsMTU2LDE1NywxNTgsMTU5LDE2MCwxNjEsMTYyLDE2MywxNjQsMTY1LDE2NiwxNjcsMTY4LDE2OSwxNzAsMTcxLDE3MiwxNzMsMTc0LDE3NSwxNzYsMTc3LDE3OCwxNzksMTgwLDE4MSwxODIsMTgzLDE4NCwxODUsMTg2LDE4NywxODgsMTg5LDE5MCwxOTEsMTkyLDE5MywxOTQsMTk1LDE5NiwxOTcsMTk4LDE5OSwyMDAsMjAxLDIwMiwyMDMsMjA0LDIwNSwyMDYsMjA3LDIwOCwyMDksMjEwLDIxMSwyMTIsMjEzLDIxNCwyMTUsMjE2LDIxNywyMTgsMjE5LDIyMCwyMjEsMjIyLDIyMywyMjQsMjI1LDIyNiwyMjcsMjI4LDIyOSwyMzAsMjMxLDIzMiwyMzMsMjM0LDIzNSwyMzYsMjM3LDIzOCwyMzksMjQwLDI0MSwyNDIsMjQzLDI0NCwyNDUsMjQ2LDI0NywyNDgsMjQ5LDI1MCwyNTEsMjUyLDI1MywyNTQsMjU1LDI1NiwyNTcsMjU4LDI1OSwyNjAsMjYxLDI2MiwyNjMsMjY0LDI2NSwyNjYsMjY3LDI2OCwyNjksMjcwLDI3MSwyNzIsMjczLDI3NCwyNzUsMjc2LDI3NywyNzgsMjc5LDI4MCwyODEsMjgyLDI4MywyODQsMjg1LDI4NiwyODcsMjg4LDI4OSwyOTAsMjkxLDI5MiwyOTMsMjk0LDI5NSwyOTYsMjk3LDI5OCwyOTksMzAwLDMwMSwzMDIsMzAzLDMwNCwzMDUsMzA2LDMwNywzMDgsMzA5LDMxMCwzMTEsMzEyLDMxMywzMTQsMzE1LDMxNiwzMTcsMzE4LDMxOSwzMjAsMzIxLDMyMiwzMjMsMzI0LDMyNSwzMjYsMzI3LDMyOCwzMjksMzMwLDMzMSwzMzIsMzMzLDMzNCwzMzUsMzM2LDMzNywzMzgsMzM5LDM0MCwzNDEsMzQyLDM0MywzNDQsMzQ1LDM0NiwzNDcsMzQ4LDM0OSwzNTAsMzUxLDM1MiwzNTMsMzU0LDM1NSwzNTYsMzU3LDM1OCwzNTksMzYwLDM2MSwzNjIsMzYzLDM2NCwzNjUsMzY2LDM2NywzNjgsMzY5LDM3MCwzNzEsMzcyLDM3MywzNzQsMzc1LDM3NiwzNzcsMzc4LDM3OSwzODAsMzgxLDM4MiwzODMsMzg0LDM4NSwzODYsMzg3LDM4OCwzODksMzkwLDM5MSwzOTIsMzkzLDM5NCwzOTUsMzk2LDM5NywzOTgsMzk5LDQwMCw0MDEsNDAyLDQwMyw0MDQsNDA1LDQwNiw0MDcsNDA4LDQwOSw0MTAsNDExLDQxMiw0MTMsNDE0LDQxNSw0MTYsNDE3LDQxOCw0MTksNDIwLDQyMSw0MjIsNDIzLDQyNCw0MjUsNDI2LDQyNyw0MjgsNDI5LDQzMCw0MzEsNDMyLDQzMyw0MzQsNDM1LDQzNiw0MzcsNDM4LDQzOSw0NDAsNDQxLDQ0Miw0NDMsNDQ0LDQ0NSw0NDYsNDQ3LDQ0OCw0NDksNDUwLDQ1MSw0NTIsNDUzLDQ1NCw0NTUsNDU2LDQ1Nyw0NTgsNDU5LDQ2MCw0NjEsNDYyLDQ2Myw0NjQsNDY1LDQ2Niw0NjcsNDY4LDQ2OSw0NzAsNDcxLDQ3Miw0NzMsNDc0LDQ3NSw0NzYsNDc3LDQ3OCw0NzksNDgwLDQ4MSw0ODIsNDgzLDQ4NCw0ODUsNDg2LDQ4Nyw0ODgsNDg5LDQ5MCw0OTEsNDkyLDQ5Myw0OTQsNDk1LDQ5Niw0OTcsNDk4LDQ5OSw1MDAsNTAxLDUwMiw1MDMsNTA0LDUwNSw1MDYsNTA3LDUwOCw1MDksNTEwLDUxMSw1MTIsNTEzLDUxNCw1MTUsNTE2LDUxNyw1MTgsNTE5LDUyMCw1MjEsNTIyLDUyMyw1MjQsNTI1LDUyNiw1MjcsNTI4LDUyOSw1MzAsNTMxLDUzMiw1MzMsNTM0LDUzNSw1MzYsNTM3LDUzOCw1MzksNTQwLDU0MSw1NDIsNTQzLDU0NCw1NDUsNTQ2LDU0Nyw1NDgsNTQ5LDU1MCw1NTEsNTUyLDU1Myw1NTQsNTU1LDU1Niw1NTcsNTU4LDU1OSw1NjAsNTYxLDU2Miw1NjMsNTY0LDU2NSw1NjYsNTY3LDU2OCw1NjksNTcwLDU3MSw1NzIsNTczLDU3NCw1NzUsNTc2LDU3Nyw1NzgsNTc5LDU4MCw1ODEsNTgyLDU4Myw1ODQsNTg1LDU4Niw1ODcsNTg4LDU4OSw1OTAsNTkxLDU5Miw1OTMsNTk0LDU5NSw1OTYsNTk3LDU5OCw1OTksNjAwLDYwMSw2MDIsNjAzLDYwNCw2MDUsNjA2LDYwNyw2MDgsNjA5LDYxMCw2MTEsNjEyLDYxMyw2MTQsNjE1LDYxNiw2MTcsNjE4LDYxOSw2MjAsNjIxLDYyMiw2MjMsNjI0LDYyNSw2MjYsNjI3LDYyOCw2MjksNjMwLDYzMSw2MzIsNjMzLDYzNCw2MzUsNjM2LDYzNyw2MzgsNjM5LDY0MCw2NDEsNjQyLDY0Myw2NDQsNjQ1LDY0Niw2NDcsNjQ4LDY0OSw2NTAsNjUxLDY1Miw2NTMsNjU0LDY1NSw2NTYsNjU3LDY1OCw2NTksNjYwLDY2MSw2NjIsNjYzLDY2NCw2NjUsNjY2LDY2Nyw2NjgsNjY5LDY3MCw2NzEsNjcyLDY3Myw2NzQsNjc1LDY3Niw2NzcsNjc4LDY3OSw2ODAsNjgxLDY4Miw2ODMsNjg0LDY4NSw2ODYsNjg3LDY4OCw2ODksNjkwLDY5MSw2OTIsNjkzLDY5NCw2OTUsNjk2LDY5Nyw2OTgsNjk5LDcwMCw3MDEsNzAyLDcwMyw3MDQsNzA1LDcwNiw3MDcsNzA4LDcwOSw3MTAsNzExLDcxMiw3MTMsNzE0LDcxNSw3MTYsNzE3LDcxOCw3MTksNzIwLDcyMSw3MjIsNzIzLDcyNCw3MjUsNzI2LDcyNyw3MjgsNzI5LDczMCw3MzEsNzMyLDczMyw3MzQsNzM1LDczNiw3MzcsNzM4LDczOSw3NDAsNzQxLDc0Miw3NDMsNzQ0LDc0NSw3NDYsNzQ3LDc0OCw3NDksNzUwLDc1MSw3NTIsNzUzLDc1NCw3NTUsNzU2LDc1Nyw3NTgsNzU5LDc2MCw3NjEsNzYyLDc2Myw3NjQsNzY1LDc2Niw3NjcsNzY4LDc2OSw3NzAsNzcxLDc3Miw3NzMsNzc0LDc3NSw3NzYsNzc3LDc3OCw3NzksNzgwLDc4MSw3ODIsNzgzLDc4NCw3ODUsNzg2LDc4Nyw3ODgsNzg5LDc5MCw3OTEsNzkyLDc5Myw3OTQsNzk1LDc5Niw3OTcsNzk4LDc5OSw4MDAsODAxLDgwMiw4MDMsODA0LDgwNSw4MDYsODA3LDgwOCw4MDksODEwLDgxMSw4MTIsODEzLDgxNCw4MTUsODE2LDgxNyw4MTgsODE5LDgyMCw4MjEsODIyLDgyMyw4MjQsODI1LDgyNiw4MjcsODI4LDgyOSw4MzAsODMxLDgzMiw4MzMsODM0LDgzNSw4MzYsODM3LDgzOCw4MzksODQwLDg0MSw4NDIsODQzLDg0NCw4NDUsODQ2LDg0Nyw4NDgsODQ5LDg1MCw4NTEsODUyLDg1Myw4NTQsODU1LDg1Niw4NTcsODU4LDg1OSw4NjAsODYxLDg2Miw4NjMsODY0LDg2NSw4NjYsODY3LDg2OCw4NjksODcwLDg3MSw4NzIsODczLDg3NCw4NzUsODc2LDg3Nyw4NzgsODc5LDg4MCw4ODEsODgyLDg4Myw4ODQsODg1LDg4Niw4ODcsODg4LDg4OSw4OTAsODkxLDg5Miw4OTMsODk0LDg5NSw4OTYsODk3LDg5OCw4OTksOTAwLDkwMSw5MDIsOTAzLDkwNCw5MDUsOTA2LDkwNyw5MDgsOTA5LDkxMCw5MTEsOTEyLDkxMyw5MTQsOTE1LDkxNiw5MTcsOTE4LDkxOSw5MjAsOTIxLDkyMiw5MjMsOTI0LDkyNSw5MjYsOTI3LDkyOCw5MjksOTMwLDkzMSw5MzIsOTMzLDkzNCw5MzUsOTM2LDkzNyw5MzgsOTM5LDk0MCw5NDEsOTQyLDk0Myw5NDQsOTQ1LDk0Niw5NDcsOTQ4LDk0OSw5NTAsOTUxLDk1Miw5NTMsOTU0LDk1NSw5NTYsOTU3LDk1OCw5NTksOTYwLDk2MSw5NjIsOTYzLDk2NCw5NjUsOTY2LDk2Nyw5NjgsOTY5LDk3MCw5NzEsOTcyLDk3Myw5NzQsOTc1LDk3Niw5NzcsOTc4LDk3OSw5ODAsOTgxLDk4Miw5ODMsOTg0LDk4NSw5ODYsOTg3LDk4OCw5ODksOTkwLDk5MSw5OTIsOTkzLDk5NCw5OTUsOTk2LDk5Nyw5OTgsOTk5LDEwMDAsMTAwMSwxMDAyLDEwMDMsMTAwNCwxMDA1LDEwMDYsMTAwNywxMDA4LDEwMDksMTAxMCwxMDExLDEwMTIsMTAxMywxMDE0LDEwMTUsMTAxNiwxMDE3LDEwMTgsMTAxOSwxMDIwLDEwMjEsMTAyMiwxMDIzLDEwMjQsMTAyNSwxMDI2LDEwMjcsMTAyOCwxMDI5LDEwMzAsMTAzMSwxMDMyLDEwMzMsMTAzNCwxMDM1LDEwMzYsMTAzNywxMDM4LDEwMzksMTA0MCwxMDQxLDEwNDIsMTA0MywxMDQ0LDEwNDUsMTA0NiwxMDQ3LDEwNDgsMTA0OSwxMDUwLDEwNTEsMTA1MiwxMDUzLDEwNTQsMTA1NSwxMDU2LDEwNTcsMTA1OCwxMDU5LDEwNjAsMTA2MSwxMDYyLDEwNjMsMTA2NCwxMDY1LDEwNjYsMTA2NywxMDY4LDEwNjksMTA3MCwxMDcxLDEwNzIsMTA3MywxMDc0LDEwNzUsMTA3NiwxMDc3LDEwNzgsMTA3OSwxMDgwLDEwODEsMTA4MiwxMDgzLDEwODQsMTA4NSwxMDg2LDEwODcsMTA4OCwxMDg5LDEwOTAsMTA5MSwxMDkyLDEwOTMsMTA5NCwxMDk1LDEwOTYsMTA5NywxMDk4LDEwOTksMTEwMCwxMTAxLDExMDIsMTEwMywxMTA0LDExMDUsMTEwNiwxMTA3LDExMDgsMTEwOSwxMTEwLDExMTEsMTExMiwxMTEzLDExMTQsMTExNSwxMTE2LDExMTcsMTExOCwxMTE5LDExMjAsMTEyMSwxMTIyLDExMjMsMTEyNCwxMTI1LDExMjYsMTEyNywxMTI4LDExMjksMTEzMCwxMTMxLDExMzIsMTEzMywxMTM0LDExMzUsMTEzNiwxMTM3LDExMzgsMTEzOSwxMTQwLDExNDEsMTE0MiwxMTQzLDExNDQsMTE0NSwxMTQ2LDExNDcsMTE0OCwxMTQ5LDExNTAsMTE1MSwxMTUyLDExNTMsMTE1NCwxMTU1LDExNTYsMTE1NywxMTU4LDExNTksMTE2MCwxMTYxLDExNjIsMTE2MywxMTY0LDExNjUsMTE2NiwxMTY3LDExNjgsMTE2OSwxMTcwLDExNzEsMTE3MiwxMTczLDExNzQsMTE3NSwxMTc2LDExNzcsMTE3OCwxMTc5LDExODAsMTE4MSwxMTgyLDExODMsMTE4NCwxMTg1LDExODYsMTE4NywxMTg4LDExODksMTE5MCwxMTkxLDExOTIsMTE5MywxMTk0LDExOTUsMTE5NiwxMTk3LDExOTgsMTE5OSwxMjAwLDEyMDEsMTIwMiwxMjAzLDEyMDQsMTIwNSwxMjA2LDEyMDcsMTIwOCwxMjA5LDEyMTAsMTIxMSwxMjEyLDEyMTMsMTIxNCwxMjE1LDEyMTYsMTIxNywxMjE4LDEyMTksMTIyMCwxMjIxLDEyMjIsMTIyMywxMjI0LDEyMjUsMTIyNiwxMjI3LDEyMjgsMTIyOSwxMjMwLDEyMzEsMTIzMiwxMjMzLDEyMzQsMTIzNSwxMjM2LDEyMzcsMTIzOCwxMjM5LDEyNDAsMTI0MSwxMjQyLDEyNDMsMTI0NCwxMjQ1LDEyNDYsMTI0NywxMjQ4LDEyNDksMTI1MCwxMjUxLDEyNTIsMTI1MywxMjU0LDEyNTUsMTI1NiwxMjU3LDEyNTgsMTI1OSwxMjYwLDEyNjEsMTI2MiwxMjYzLDEyNjQsMTI2NSwxMjY2LDEyNjcsMTI2OCwxMjY5LDEyNzAsMTI3MSwxMjcyLDEyNzMsMTI3NCwxMjc1LDEyNzYsMTI3NywxMjc4LDEyNzksMTI4MCwxMjgxLDEyODIsMTI4MywxMjg0LDEyODUsMTI4NiwxMjg3LDEyODgsMTI4OSwxMjkwLDEyOTEsMTI5MiwxMjkzLDEyOTQsMTI5NSwxMjk2LDEyOTcsMTI5OCwxMjk5LDEzMDAsMTMwMSwxMzAyLDEzMDMsMTMwNCwxMzA1LDEzMDYsMTMwNywxMzA4LDEzMDksMTMxMCwxMzExLDEzMTIsMTMxMywxMzE0LDEzMTUsMTMxNiwxMzE3LDEzMTgsMTMxOSwxMzIwLDEzMjEsMTMyMiwxMzIzLDEzMjQsMTMyNSwxMzI2LDEzMjcsMTMyOCwxMzI5LDEzMzAsMTMzMSwxMzMyLDEzMzMsMTMzNCwxMzM1LDEzMzYsMTMzNywxMzM4LDEzMzksMTM0MCwxMzQxLDEzNDIsMTM0MywxMzQ0LDEzNDUsMTM0NiwxMzQ3LDEzNDgsMTM0OSwxMzUwLDEzNTEsMTM1MiwxMzUzLDEzNTQsMTM1NSwxMzU2LDEzNTcsMTM1OCwxMzU5LDEzNjAsMTM2MSwxMzYyLDEzNjMsMTM2NCwxMzY1LDEzNjYsMTM2NywxMzY4LDEzNjksMTM3MCwxMzcxLDEzNzIsMTM3MywxMzc0LDEzNzUsMTM3NiwxMzc3LDEzNzgsMTM3OSwxMzgwLDEzODEsMTM4MiwxMzgzLDEzODQsMTM4NSwxMzg2LDEzODcsMTM4OCwxMzg5LDEzOTAsMTM5MSwxMzkyLDEzOTMsMTM5NCwxMzk1LDEzOTYsMTM5NywxMzk4LDEzOTksMTQwMCwxNDAxLDE0MDIsMTQwMywxNDA0LDE0MDUsMTQwNiwxNDA3LDE0MDgsMTQwOSwxNDEwLDE0MTEsMTQxMiwxNDEzLDE0MTQsMTQxNSwxNDE2LDE0MTcsMTQxOCwxNDE5LDE0MjAsMTQyMSwxNDIyLDE0MjMsMTQyNCwxNDI1LDE0MjYsMTQyNywxNDI4LDE0MjksMTQzMCwxNDMxLDE0MzIsMTQzMywxNDM0LDE0MzUsMTQzNiwxNDM3LDE0MzgsMTQzOSwxNDQwLDE0NDEsMTQ0MiwxNDQzLDE0NDQsMTQ0NSwxNDQ2LDE0NDcsMTQ0OCwxNDQ5LDE0NTAsMTQ1MSwxNDUyLDE0NTMsMTQ1NCwxNDU1LDE0NTYsMTQ1NywxNDU4LDE0NTksMTQ2MCwxNDYxLDE0NjIsMTQ2MywxNDY0LDE0NjUsMTQ2NiwxNDY3LDE0NjgsMTQ2OSwxNDcwLDE0NzEsMTQ3MiwxNDczLDE0NzQsMTQ3NSwxNDc2LDE0NzcsMTQ3OCwxNDc5LDE0ODAsMTQ4MSwxNDgyLDE0ODMsMTQ4NCwxNDg1LDE0ODYsMTQ4NywxNDg4LDE0ODksMTQ5MCwxNDkxLDE0OTIsMTQ5MywxNDk0LDE0OTUsMTQ5NiwxNDk3LDE0OTgsMTQ5OSwxNTAwLDE1MDEsMTUwMiwxNTAzLDE1MDQsMTUwNSwxNTA2LDE1MDcsMTUwOCwxNTA5LDE1MTAsMTUxMSwxNTEyLDE1MTMsMTUxNCwxNTE1LDE1MTYsMTUxNywxNTE4LDE1MTksMTUyMCwxNTIxLDE1MjIsMTUyMywxNTI0LDE1MjUsMTUyNiwxNTI3LDE1MjgsMTUyOSwxNTMwLDE1MzEsMTUzMiwxNTMzLDE1MzQsMTUzNSwxNTM2LDE1MzcsMTUzOCwxNTM5LDE1NDAsMTU0MSwxNTQyLDE1NDMsMTU0NCwxNTQ1LDE1NDYsMTU0NywxNTQ4LDE1NDksMTU1MCwxNTUxLDE1NTIsMTU1MywxNTU0LDE1NTUsMTU1NiwxNTU3LDE1NTgsMTU1OSwxNTYwLDE1NjEsMTU2MiwxNTYzLDE1NjQsMTU2NSwxNTY2LDE1NjcsMTU2OCwxNTY5LDE1NzAsMTU3MSwxNTcyLDE1NzMsMTU3NCwxNTc1LDE1NzYsMTU3NywxNTc4LDE1NzksMTU4MCwxNTgxLDE1ODIsMTU4MywxNTg0LDE1ODUsMTU4NiwxNTg3LDE1ODgsMTU4OSwxNTkwLDE1OTEsMTU5MiwxNTkzLDE1OTQsMTU5NSwxNTk2LDE1OTcsMTU5OCwxNTk5LDE2MDAsMTYwMSwxNjAyLDE2MDMsMTYwNCwxNjA1LDE2MDYsMTYwNywxNjA4LDE2MDksMTYxMCwxNjExLDE2MTIsMTYxMywxNjE0LDE2MTUsMTYxNiwxNjE3LDE2MTgsMTYxOSwxNjIwLDE2MjEsMTYyMiwxNjIzLDE2MjQsMTYyNSwxNjI2LDE2MjcsMTYyOCwxNjI5LDE2MzAsMTYzMSwxNjMyLDE2MzMsMTYzNCwxNjM1LDE2MzYsMTYzNywxNjM4LDE2MzksMTY0MCwxNjQxLDE2NDIsMTY0MywxNjQ0LDE2NDUsMTY0NiwxNjQ3LDE2NDgsMTY0OSwxNjUwLDE2NTEsMTY1MiwxNjUzLDE2NTQsMTY1NSwxNjU2LDE2NTcsMTY1OCwxNjU5LDE2NjAsMTY2MSwxNjYyLDE2NjMsMTY2NCwxNjY1LDE2NjYsMTY2NywxNjY4LDE2NjksMTY3MCwxNjcxLDE2NzIsMTY3MywxNjc0LDE2NzUsMTY3NiwxNjc3LDE2NzgsMTY3OSwxNjgwLDE2ODEsMTY4MiwxNjgzLDE2ODQsMTY4NSwxNjg2LDE2ODcsMTY4OCwxNjg5LDE2OTAsMTY5MSwxNjkyLDE2OTMsMTY5NCwxNjk1LDE2OTYsMTY5NywxNjk4LDE2OTksMTcwMCwxNzAxLDE3MDIsMTcwMywxNzA0LDE3MDUsMTcwNiwxNzA3LDE3MDgsMTcwOSwxNzEwLDE3MTEsMTcxMiwxNzEzLDE3MTQsMTcxNSwxNzE2LDE3MTcsMTcxOCwxNzE5LDE3MjAsMTcyMSwxNzIyLDE3MjMsMTcyNCwxNzI1LDE3MjYsMTcyNywxNzI4LDE3MjksMTczMCwxNzMxLDE3MzIsMTczMywxNzM0LDE3MzUsMTczNiwxNzM3LDE3MzgsMTczOSwxNzQwLDE3NDEsMTc0MiwxNzQzLDE3NDQsMTc0NSwxNzQ2LDE3NDcsMTc0OCwxNzQ5LDE3NTAsMTc1MSwxNzUyLDE3NTMsMTc1NCwxNzU1LDE3NTYsMTc1NywxNzU4LDE3NTksMTc2MCwxNzYxLDE3NjIsMTc2MywxNzY0LDE3NjUsMTc2NiwxNzY3LDE3NjgsMTc2OSwxNzcwLDE3NzEsMTc3MiwxNzczLDE3NzQsMTc3NSwxNzc2LDE3NzcsMTc3OCwxNzc5LDE3ODAsMTc4MSwxNzgyLDE3ODMsMTc4NCwxNzg1LDE3ODYsMTc4NywxNzg4LDE3ODksMTc5MCwxNzkxLDE3OTIsMTc5MywxNzk0LDE3OTUsMTc5NiwxNzk3LDE3OTgsMTc5OSwxODAwLDE4MDEsMTgwMiwxODAzLDE4MDQsMTgwNSwxODA2LDE4MDcsMTgwOCwxODA5LDE4MTAsMTgxMSwxODEyLDE4MTMsMTgxNCwxODE1LDE4MTYsMTgxNywxODE4LDE4MTksMTgyMCwxODIxLDE4MjIsMTgyMywxODI0LDE4MjUsMTgyNiwxODI3LDE4MjgsMTgyOSwxODMwLDE4MzEsMTgzMiwxODMzLDE4MzQsMTgzNSwxODM2LDE4MzcsMTgzOCwxODM5LDE4NDAsMTg0MSwxODQyLDE4NDMsMTg0NCwxODQ1LDE4NDYsMTg0NywxODQ4LDE4NDksMTg1MCwxODUxLDE4NTIsMTg1MywxODU0LDE4NTUsMTg1NiwxODU3LDE4NTgsMTg1OSwxODYwLDE4NjEsMTg2MiwxODYzLDE4NjQsMTg2NSwxODY2LDE4NjcsMTg2OCwxODY5LDE4NzAsMTg3MSwxODcyLDE4NzMsMTg3NCwxODc1LDE4NzYsMTg3NywxODc4LDE4NzksMTg4MCwxODgxLDE4ODIsMTg4MywxODg0LDE4ODUsMTg4NiwxODg3LDE4ODgsMTg4OSwxODkwLDE4OTEsMTg5MiwxODkzLDE4OTQsMTg5NSwxODk2LDE4OTcsMTg5OCwxODk5LDE5MDAsMTkwMSwxOTAyLDE5MDMsMTkwNCwxOTA1LDE5MDYsMTkwNywxOTA4LDE5MDksMTkxMCwxOTExLDE5MTIsMTkxMywxOTE0LDE5MTUsMTkxNiwxOTE3LDE5MTgsMTkxOSwxOTIwLDE5MjEsMTkyMiwxOTIzLDE5MjQsMTkyNSwxOTI2LDE5MjcsMTkyOCwxOTI5LDE5MzAsMTkzMSwxOTMyLDE5MzMsMTkzNCwxOTM1LDE5MzYsMTkzNywxOTM4LDE5MzksMTk0MCwxOTQxLDE5NDIsMTk0MywxOTQ0LDE5NDUsMTk0NiwxOTQ3LDE5NDgsMTk0OSwxOTUwLDE5NTEsMTk1MiwxOTUzLDE5NTQsMTk1NSwxOTU2LDE5NTcsMTk1OCwxOTU5LDE5NjAsMTk2MSwxOTYyLDE5NjMsMTk2NCwxOTY1LDE5NjYsMTk2NywxOTY4LDE5NjksMTk3MCwxOTcxLDE5NzIsMTk3MywxOTc0LDE5NzUsMTk3NiwxOTc3LDE5NzgsMTk3OSwxOTgwLDE5ODEsMTk4MiwxOTgzLDE5ODQsMTk4NSwxOTg2LDE5ODcsMTk4OCwxOTg5LDE5OTAsMTk5MSwxOTkyLDE5OTMsMTk5NCwxOTk1LDE5OTYsMTk5NywxOTk4LDE5OTksMjAwMF0='));

// Typical User object
JSON.parse(atob('eyJpZCI6MSwiZ2l2ZW5fbmFtZSI6IlRlc3QiLCJmYW1pbHlfbmFtZSI6IlVzZXIiLCJzdWZmaXgiOm51bGwsImRpc3BsYXlfbmFtZSI6IlN5c3RlbSIsImxlZ2FsX25hbWUiOiJTeXN0ZW0iLCJ1c2VybmFtZSI6InRlc3QiLCJyb2xlIjoiZ3Vlc3QiLCJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJlbWFpbDIiOm51bGwsInBob3RvIjpudWxsLCJhdmF0YXJfdXBsb2FkX2lkIjpudWxsLCJsb2NhbGUiOiJlbiIsInRpbWV6b25lIjoiQW1lcmljYVwvTmV3X1lvcmsiLCJsYXRpdHVkZSI6bnVsbCwibG9uZ2l0dWRlIjpudWxsLCJjb25maXJtZWQiOnRydWUsImNyZWF0ZWRfYXQiOiIxOTk3LTAxLTAxIDAwOjAwOjAwIiwidXBkYXRlZF9hdCI6IjE5OTctMDEtMDEgMDA6MDA6MDAiLCJhY2NvdW50X2lkIjoxLCJwdWJsaWNfaWQiOm51bGwsImFnZ3JlZ2F0ZV9yb2xlIjoiZ3Vlc3QifQ=='));

@inxilpro inxilpro changed the title [8.x] Introduce JsString for encoding data to use in JavaScript [8.x] Introduce JsString for encoding data to use in JavaScript Nov 3, 2021
@inxilpro
Copy link
Contributor Author

inxilpro commented Nov 3, 2021

It's also worth noting that some of the reasoning behind using JSON.parse rather than just dumping the JSON object directly comes from the research that the V8 team did on performance. It's an interesting read if you're into that kind of thing :)

@taylorotwell
Copy link
Member

@inxilpro can this be used in all the exact same scenarios as the previous version? Within quotes, within Blade components, etc.?

@DarkGhostHunter
Copy link
Contributor

Could a root function be used instead? Like js_string()? This would avoid namespacing the helper.

@inxilpro
Copy link
Contributor Author

inxilpro commented Nov 4, 2021

@taylorotwell Yep, it's built to handle all the same scenarios.

@inxilpro
Copy link
Contributor Author

inxilpro commented Nov 4, 2021

@DarkGhostHunter the concern is about adding a new global helper. I think for right now it may be better to just add the helper in your own codebase if you want it. As long as we add an alias for JsString to the default app.php config you can just do:

<div x-data="{{ JsString::from($data) }}">
...
</div>

<!-- or -->

<script>
let foo = {{ JsString::from($foo) }};
</script>

If you want to, you can then add you own helper:

if (! function_exists('js')) {
  function js($data, $flags = 0, $depth = 512) {
    return new JsString($data, $flags, $depth);
  }
}

@taylorotwell
Copy link
Member

So does JsString::from read better than Js::from? Js::from seems so much nicer to me?

@inxilpro
Copy link
Contributor Author

inxilpro commented Nov 4, 2021

So does JsString::from read better than Js::from? Js::from seems so much nicer to me?

Yeah, Js::from definitely reads better. My preference would be that you use @js() most of the time (see #39478) and that when you need to instantiate a JsString you use new JsString(). I've really just been using JsString::from() as a parallel to the original PR.

So in the end, the typical usage would be:

<!-- for HTML attributes, use @js() -->
<div x-data="@js($data)"></div>

<!-- for inline JS, use @js() -->
<script>
let data = @js($data);
</script>

<!-- for Blade components, use JsString -->
<x-alert :data="new JsString($data)" />

For the Blade component case, I'd probably bake that into my component such that it accepts any :data and wraps it in a JsString so that the consuming code doesn't have to worry about it.

@inxilpro
Copy link
Contributor Author

inxilpro commented Nov 4, 2021

I just pushed an update that makes JsString objects "self-aware" so that if you call new JsString($existingJsString) you get the original javascript expression, not a javascript string representation of the original expression. This lets you just always wrap data inside of a blade component:

For example:

{{-- modal.blade.php --}}

@props(['config' => new stdClass()])
<div {{ $attributes->except('x-data') }} x-data="{ open: false, config: @js($config) }">
  {{ $slot }}
</div>

{{-- Both of these would work: --}}

<x-modal :config="$data" />
<x-modal :config="new JsString($data)" />

This way you can just always use the @js() helper in your blade component's view, and eliminate the need for the third example above most of the time. This puts JsString in the same bucket as HtmlString — it's there when you need it but most of the time you don't have to think about it. No one needs to know that csrf_field() or $slot use HtmlString under the hood—it just works. But once you need the functionality, the class is there for you to use.

@inxilpro
Copy link
Contributor Author

inxilpro commented Nov 4, 2021

(That said, I'm OK with renaming it back to Js if that's a major hangup for you. It feels a little too non-specific to me, but it's not a hill I'll die on!)

@taylorotwell taylorotwell merged commit 4965ce3 into laravel:8.x Nov 5, 2021
@taylorotwell
Copy link
Member

Renamed the class back to Js.

@taylorotwell
Copy link
Member

Thanks for contributing to Laravel! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants