Skip to content

Commit 05d37e6

Browse files
Remove old IE support (#3277)
* Remove old IE support * don't need regex in normalizePath * fix verifyPath to handle about: situations like some iframes now that there is no fallback * improve diff * fix logic mistake in last diff improvment * Update url normlization test post testing upgrade * remove un-needed document
1 parent d3bcd78 commit 05d37e6

2 files changed

Lines changed: 35 additions & 93 deletions

File tree

src/htmx.js

Lines changed: 31 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,7 @@ var htmx = (function() {
489489
* @returns {boolean}
490490
*/
491491
function matches(elt, selector) {
492-
// @ts-ignore: non-standard properties for browser compatibility
493-
// noinspection JSUnresolvedVariable
494-
const matchesFunction = elt instanceof Element && (elt.matches || elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector || elt.webkitMatchesSelector || elt.oMatchesSelector)
495-
return !!matchesFunction && matchesFunction.call(elt, selector)
492+
return elt instanceof Element && elt.matches(selector)
496493
}
497494

498495
/**
@@ -830,20 +827,16 @@ var htmx = (function() {
830827
* @returns {string}
831828
*/
832829
function normalizePath(path) {
833-
try {
834-
const url = new URL(path)
835-
if (url) {
836-
path = url.pathname + url.search
837-
}
838-
// remove trailing slash, unless index page
839-
if (!(/^\/$/.test(path))) {
840-
path = path.replace(/\/+$/, '')
841-
}
842-
return path
843-
} catch (e) {
844-
// be kind to IE11, which doesn't support URL()
845-
return path
830+
// use dummy base URL to allow normalize on path only
831+
const url = new URL(path, 'http://x')
832+
if (url) {
833+
path = url.pathname + url.search
846834
}
835+
// remove trailing slash, unless index page
836+
if (path != '/') {
837+
path = path.replace(/\/+$/, '')
838+
}
839+
return path
847840
}
848841

849842
//= =========================================================================================
@@ -1079,18 +1072,10 @@ var htmx = (function() {
10791072
*/
10801073
function closest(elt, selector) {
10811074
elt = asElement(resolveTarget(elt))
1082-
if (elt && elt.closest) {
1075+
if (elt) {
10831076
return elt.closest(selector)
1084-
} else {
1085-
// TODO remove when IE goes away
1086-
do {
1087-
if (elt == null || matches(elt, selector)) {
1088-
return elt
1089-
}
1090-
}
1091-
while (elt = elt && asElement(parentElt(elt)))
1092-
return null
10931077
}
1078+
return null
10941079
}
10951080

10961081
/**
@@ -1403,13 +1388,7 @@ var htmx = (function() {
14031388
* @returns {boolean}
14041389
*/
14051390
function shouldSettleAttribute(name) {
1406-
const attributesToSettle = htmx.config.attributesToSettle
1407-
for (let i = 0; i < attributesToSettle.length; i++) {
1408-
if (name === attributesToSettle[i]) {
1409-
return true
1410-
}
1411-
}
1412-
return false
1391+
return htmx.config.attributesToSettle.includes(name)
14131392
}
14141393

14151394
/**
@@ -1631,14 +1610,11 @@ var htmx = (function() {
16311610
*/
16321611
function attributeHash(elt) {
16331612
let hash = 0
1634-
// IE fix
1635-
if (elt.attributes) {
1636-
for (let i = 0; i < elt.attributes.length; i++) {
1637-
const attribute = elt.attributes[i]
1638-
if (attribute.value) { // only include attributes w/ actual values (empty is same as non-existent)
1639-
hash = stringHash(attribute.name, hash)
1640-
hash = stringHash(attribute.value, hash)
1641-
}
1613+
for (let i = 0; i < elt.attributes.length; i++) {
1614+
const attribute = elt.attributes[i]
1615+
if (attribute.value) { // only include attributes w/ actual values (empty is same as non-existent)
1616+
hash = stringHash(attribute.name, hash)
1617+
hash = stringHash(attribute.value, hash)
16421618
}
16431619
}
16441620
return hash
@@ -1683,12 +1659,8 @@ var htmx = (function() {
16831659
function cleanUpElement(element) {
16841660
triggerEvent(element, 'htmx:beforeCleanupElement')
16851661
deInitNode(element)
1686-
// @ts-ignore IE11 code
1687-
// noinspection JSUnresolvedReference
1688-
if (element.children) { // IE
1689-
// @ts-ignore
1690-
forEach(element.children, function(child) { cleanUpElement(child) })
1691-
}
1662+
// @ts-ignore
1663+
forEach(element.children, function(child) { cleanUpElement(child) })
16921664
}
16931665

16941666
/**
@@ -2896,6 +2868,8 @@ var htmx = (function() {
28962868
cleanUpElement(elt)
28972869
return
28982870
}
2871+
// Ensure only valid Elements and not shadow DOM roots are inited
2872+
if (!(elt instanceof Element)) return
28992873
const nodeData = getInternalData(elt)
29002874
const attrHash = attributeHash(elt)
29012875
if (nodeData.initHash !== attrHash) {
@@ -2968,16 +2942,9 @@ var htmx = (function() {
29682942
* @returns {CustomEvent}
29692943
*/
29702944
function makeEvent(eventName, detail) {
2971-
let evt
2972-
if (window.CustomEvent && typeof window.CustomEvent === 'function') {
2973-
// TODO: `composed: true` here is a hack to make global event handlers work with events in shadow DOM
2974-
// This breaks expected encapsulation but needs to be here until decided otherwise by core devs
2975-
evt = new CustomEvent(eventName, { bubbles: true, cancelable: true, composed: true, detail })
2976-
} else {
2977-
evt = getDocument().createEvent('CustomEvent')
2978-
evt.initCustomEvent(eventName, true, true, detail)
2979-
}
2980-
return evt
2945+
// TODO: `composed: true` here is a hack to make global event handlers work with events in shadow DOM
2946+
// This breaks expected encapsulation but needs to be here until decided otherwise by core devs
2947+
return new CustomEvent(eventName, { bubbles: true, cancelable: true, composed: true, detail })
29812948
}
29822949

29832950
/**
@@ -3017,11 +2984,7 @@ var htmx = (function() {
30172984
}
30182985

30192986
function logError(msg) {
3020-
if (console.error) {
3021-
console.error(msg)
3022-
} else if (console.log) {
3023-
console.log('ERROR: ', msg)
3024-
}
2987+
console.error(msg)
30252988
}
30262989

30272990
/**
@@ -3179,13 +3142,7 @@ var htmx = (function() {
31793142
// so we can prevent privileged data entering the cache.
31803143
// The page will still be reachable as a history entry, but htmx will fetch it
31813144
// live from the server onpopstate rather than look in the localStorage cache
3182-
let disableHistoryCache
3183-
try {
3184-
disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]')
3185-
} catch (e) {
3186-
// IE11: insensitive modifier not supported so fallback to case sensitive selector
3187-
disableHistoryCache = getDocument().querySelector('[hx-history="false"],[data-hx-history="false"]')
3188-
}
3145+
const disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]')
31893146
if (!disableHistoryCache) {
31903147
triggerEvent(getDocument().body, 'htmx:beforeHistorySave', { path, historyElt: elt })
31913148
saveToHistoryCache(path, elt)
@@ -3931,8 +3888,7 @@ var htmx = (function() {
39313888
* @return {string}
39323889
*/
39333890
function getPathFromResponse(xhr) {
3934-
// NB: IE11 does not support this stuff
3935-
if (xhr.responseURL && typeof (URL) !== 'undefined') {
3891+
if (xhr.responseURL) {
39363892
try {
39373893
const url = new URL(xhr.responseURL)
39383894
return url.pathname + url.search
@@ -4014,17 +3970,9 @@ var htmx = (function() {
40143970
* @return {boolean}
40153971
*/
40163972
function verifyPath(elt, path, requestConfig) {
4017-
let sameHost
4018-
let url
4019-
if (typeof URL === 'function') {
4020-
url = new URL(path, document.location.href)
4021-
const origin = document.location.origin
4022-
sameHost = origin === url.origin
4023-
} else {
4024-
// IE11 doesn't support URL
4025-
url = path
4026-
sameHost = startsWith(path, document.location.origin)
4027-
}
3973+
const url = new URL(path, location.protocol !== 'about:' ? location.href : window.origin)
3974+
const origin = location.protocol !== 'about:' ? location.origin : window.origin
3975+
const sameHost = origin === url.origin
40283976

40293977
if (htmx.config.selfRequestsOnly) {
40303978
if (!sameHost) {

test/attributes/hx-push-url.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ describe('hx-push-url attribute', function() {
5050
getWorkArea().textContent.should.equal('second')
5151
var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME))
5252
cache.length.should.equal(2)
53-
cache[1].url.should.equal('abc123')
54-
// the url should be normalized with a / but this code has an issue right now
55-
// cache[1].url.should.equal('/abc123')
53+
cache[1].url.should.equal('/abc123')
5654
})
5755

5856
it('restore should return old value', function() {
@@ -199,13 +197,9 @@ describe('hx-push-url attribute', function() {
199197
htmx._('saveToHistoryCache')('url1', make('<div>'))
200198
var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME))
201199
cache.length.should.equal(3)
202-
cache[0].url.should.equal('url3')
203-
cache[1].url.should.equal('url2')
204-
cache[2].url.should.equal('url1')
205-
// the paths should be normalized with a / but normalization has a bug right now
206-
// cache[0].url.should.equal('/url3')
207-
// cache[1].url.should.equal('/url2')
208-
// cache[2].url.should.equal('/url1')
200+
cache[0].url.should.equal('/url3')
201+
cache[1].url.should.equal('/url2')
202+
cache[2].url.should.equal('/url1')
209203
})
210204

211205
it('htmx:afterSettle is called when replacing outerHTML', function() {

0 commit comments

Comments
 (0)