mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-27 13:01:03 +00:00
Make htmx IE11 compatible again + tests IE11 compatible (#1687)
* Make htmx IE11 compatible again + tests IE11 compatible * IE11 compatible handmade socket mock for ws-ext tests * Fallback when xpath isn't supported, hx-on wildcard now working on IE11 * Merge remote-tracking branch 'upstream/relative-url-in-hx-boost' into ie11-compatibility
This commit is contained in:
parent
1763cfc64e
commit
55c30b5607
237
package-lock.json
generated
237
package-lock.json
generated
@ -1,27 +1,24 @@
|
||||
{
|
||||
"name": "htmx.org",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "htmx.org",
|
||||
"version": "1.9.3",
|
||||
"version": "1.9.5",
|
||||
"license": "BSD 2-Clause",
|
||||
"devDependencies": {
|
||||
"chai": "^4.3.7",
|
||||
"chai-dom": "^1.11.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"mocha": "^10.2.0",
|
||||
"mocha": "^9.2.2",
|
||||
"mocha-chrome": "^2.2.0",
|
||||
"mocha-webdriver-runner": "^0.6.4",
|
||||
"mock-socket": "^9.2.1",
|
||||
"sinon": "^9.2.4",
|
||||
"typescript": "^4.9.5",
|
||||
"uglify-js": "^3.17.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "15.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinonjs/commons": {
|
||||
@ -65,6 +62,12 @@
|
||||
"integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@ungap/promise-all-settled": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
|
||||
"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@zbigg/treesync": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@zbigg/treesync/-/treesync-0.3.0.tgz",
|
||||
@ -385,23 +388,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
|
||||
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/debug/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
@ -625,6 +627,15 @@
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
@ -795,6 +806,12 @@
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
@ -1059,39 +1076,46 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
|
||||
"integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
|
||||
"integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ungap/promise-all-settled": "1.1.2",
|
||||
"ansi-colors": "4.1.1",
|
||||
"browser-stdout": "1.3.1",
|
||||
"chokidar": "3.5.3",
|
||||
"debug": "4.3.4",
|
||||
"debug": "4.3.3",
|
||||
"diff": "5.0.0",
|
||||
"escape-string-regexp": "4.0.0",
|
||||
"find-up": "5.0.0",
|
||||
"glob": "7.2.0",
|
||||
"growl": "1.10.5",
|
||||
"he": "1.2.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"log-symbols": "4.1.0",
|
||||
"minimatch": "5.0.1",
|
||||
"minimatch": "4.2.1",
|
||||
"ms": "2.1.3",
|
||||
"nanoid": "3.3.3",
|
||||
"nanoid": "3.3.1",
|
||||
"serialize-javascript": "6.0.0",
|
||||
"strip-json-comments": "3.1.1",
|
||||
"supports-color": "8.1.1",
|
||||
"workerpool": "6.2.1",
|
||||
"which": "2.0.2",
|
||||
"workerpool": "6.2.0",
|
||||
"yargs": "16.2.0",
|
||||
"yargs-parser": "20.2.4",
|
||||
"yargs-unparser": "2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"_mocha": "bin/_mocha",
|
||||
"mocha": "bin/mocha.js"
|
||||
"mocha": "bin/mocha"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.0.0"
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mochajs"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha-chrome": {
|
||||
@ -1118,15 +1142,6 @@
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha-chrome/node_modules/debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha-webdriver-runner": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/mocha-webdriver-runner/-/mocha-webdriver-runner-0.6.4.tgz",
|
||||
@ -1289,26 +1304,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/minimatch": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
|
||||
"integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@ -1409,9 +1415,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nanoassert": {
|
||||
@ -1432,9 +1438,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
|
||||
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
|
||||
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
@ -2166,10 +2172,25 @@
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/workerpool": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
|
||||
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
|
||||
"integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
@ -2325,6 +2346,12 @@
|
||||
"integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==",
|
||||
"dev": true
|
||||
},
|
||||
"@ungap/promise-all-settled": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
|
||||
"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@zbigg/treesync": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@zbigg/treesync/-/treesync-0.3.0.tgz",
|
||||
@ -2587,20 +2614,12 @@
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
|
||||
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"decamelize": {
|
||||
@ -2779,6 +2798,12 @@
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
@ -2907,6 +2932,12 @@
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
@ -3138,29 +3169,32 @@
|
||||
}
|
||||
},
|
||||
"mocha": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
|
||||
"integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
|
||||
"integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@ungap/promise-all-settled": "1.1.2",
|
||||
"ansi-colors": "4.1.1",
|
||||
"browser-stdout": "1.3.1",
|
||||
"chokidar": "3.5.3",
|
||||
"debug": "4.3.4",
|
||||
"debug": "4.3.3",
|
||||
"diff": "5.0.0",
|
||||
"escape-string-regexp": "4.0.0",
|
||||
"find-up": "5.0.0",
|
||||
"glob": "7.2.0",
|
||||
"growl": "1.10.5",
|
||||
"he": "1.2.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"log-symbols": "4.1.0",
|
||||
"minimatch": "5.0.1",
|
||||
"minimatch": "4.2.1",
|
||||
"ms": "2.1.3",
|
||||
"nanoid": "3.3.3",
|
||||
"nanoid": "3.3.1",
|
||||
"serialize-javascript": "6.0.0",
|
||||
"strip-json-comments": "3.1.1",
|
||||
"supports-color": "8.1.1",
|
||||
"workerpool": "6.2.1",
|
||||
"which": "2.0.2",
|
||||
"workerpool": "6.2.0",
|
||||
"yargs": "16.2.0",
|
||||
"yargs-parser": "20.2.4",
|
||||
"yargs-unparser": "2.0.0"
|
||||
@ -3271,23 +3305,12 @@
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
|
||||
"integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
}
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
@ -3377,17 +3400,6 @@
|
||||
"loglevel": "^1.4.1",
|
||||
"meow": "^5.0.0",
|
||||
"nanobus": "^4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mocha-webdriver-runner": {
|
||||
@ -3417,9 +3429,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"nanoassert": {
|
||||
@ -3440,9 +3452,9 @@
|
||||
}
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
|
||||
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
|
||||
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
|
||||
"dev": true
|
||||
},
|
||||
"nanoscheduler": {
|
||||
@ -4040,10 +4052,19 @@
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"workerpool": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
|
||||
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
|
||||
"integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
|
@ -39,7 +39,7 @@
|
||||
"chai": "^4.3.7",
|
||||
"chai-dom": "^1.11.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"mocha": "^10.2.0",
|
||||
"mocha": "^9.2.2",
|
||||
"mocha-chrome": "^2.2.0",
|
||||
"mocha-webdriver-runner": "^0.6.4",
|
||||
"mock-socket": "^9.2.1",
|
||||
|
@ -25,28 +25,28 @@
|
||||
if (delayElt) {
|
||||
const delayInMilliseconds =
|
||||
delayElt.getAttribute('data-loading-delay') || 200
|
||||
const timeout = setTimeout(() => {
|
||||
const timeout = setTimeout(function () {
|
||||
doCallback()
|
||||
|
||||
loadingStatesUndoQueue.push(() => {
|
||||
mayProcessUndoCallback(targetElt, () => undoCallback())
|
||||
loadingStatesUndoQueue.push(function () {
|
||||
mayProcessUndoCallback(targetElt, undoCallback)
|
||||
})
|
||||
}, delayInMilliseconds)
|
||||
|
||||
loadingStatesUndoQueue.push(() => {
|
||||
mayProcessUndoCallback(targetElt, () => clearTimeout(timeout))
|
||||
loadingStatesUndoQueue.push(function () {
|
||||
mayProcessUndoCallback(targetElt, function () { clearTimeout(timeout) })
|
||||
})
|
||||
} else {
|
||||
doCallback()
|
||||
loadingStatesUndoQueue.push(() => {
|
||||
mayProcessUndoCallback(targetElt, () => undoCallback())
|
||||
loadingStatesUndoQueue.push(function () {
|
||||
mayProcessUndoCallback(targetElt, undoCallback)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getLoadingStateElts(loadingScope, type, path) {
|
||||
return Array.from(htmx.findAll(loadingScope, `[${type}]`)).filter(
|
||||
(elt) => mayProcessLoadingStateByPath(elt, path)
|
||||
return Array.from(htmx.findAll(loadingScope, "[" + type + "]")).filter(
|
||||
function (elt) { return mayProcessLoadingStateByPath(elt, path) }
|
||||
)
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
|
||||
let loadingStateEltsByType = {}
|
||||
|
||||
loadingStateTypes.forEach((type) => {
|
||||
loadingStateTypes.forEach(function (type) {
|
||||
loadingStateEltsByType[type] = getLoadingStateElts(
|
||||
container,
|
||||
type,
|
||||
@ -82,87 +82,91 @@
|
||||
)
|
||||
})
|
||||
|
||||
loadingStateEltsByType['data-loading'].forEach((sourceElt) => {
|
||||
getLoadingTarget(sourceElt).forEach((targetElt) => {
|
||||
loadingStateEltsByType['data-loading'].forEach(function (sourceElt) {
|
||||
getLoadingTarget(sourceElt).forEach(function (targetElt) {
|
||||
queueLoadingState(
|
||||
sourceElt,
|
||||
targetElt,
|
||||
() =>
|
||||
(targetElt.style.display =
|
||||
function () {
|
||||
targetElt.style.display =
|
||||
sourceElt.getAttribute('data-loading') ||
|
||||
'inline-block'),
|
||||
() => (targetElt.style.display = 'none')
|
||||
'inline-block' },
|
||||
function () { targetElt.style.display = 'none' }
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
loadingStateEltsByType['data-loading-class'].forEach(
|
||||
(sourceElt) => {
|
||||
function (sourceElt) {
|
||||
const classNames = sourceElt
|
||||
.getAttribute('data-loading-class')
|
||||
.split(' ')
|
||||
|
||||
getLoadingTarget(sourceElt).forEach((targetElt) => {
|
||||
getLoadingTarget(sourceElt).forEach(function (targetElt) {
|
||||
queueLoadingState(
|
||||
sourceElt,
|
||||
targetElt,
|
||||
() =>
|
||||
classNames.forEach((className) =>
|
||||
targetElt.classList.add(className)
|
||||
),
|
||||
() =>
|
||||
classNames.forEach((className) =>
|
||||
targetElt.classList.remove(className)
|
||||
)
|
||||
function () {
|
||||
classNames.forEach(function (className) {
|
||||
targetElt.classList.add(className)
|
||||
})
|
||||
},
|
||||
function() {
|
||||
classNames.forEach(function (className) {
|
||||
targetElt.classList.remove(className)
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
loadingStateEltsByType['data-loading-class-remove'].forEach(
|
||||
(sourceElt) => {
|
||||
function (sourceElt) {
|
||||
const classNames = sourceElt
|
||||
.getAttribute('data-loading-class-remove')
|
||||
.split(' ')
|
||||
|
||||
getLoadingTarget(sourceElt).forEach((targetElt) => {
|
||||
getLoadingTarget(sourceElt).forEach(function (targetElt) {
|
||||
queueLoadingState(
|
||||
sourceElt,
|
||||
targetElt,
|
||||
() =>
|
||||
classNames.forEach((className) =>
|
||||
targetElt.classList.remove(className)
|
||||
),
|
||||
() =>
|
||||
classNames.forEach((className) =>
|
||||
targetElt.classList.add(className)
|
||||
)
|
||||
function () {
|
||||
classNames.forEach(function (className) {
|
||||
targetElt.classList.remove(className)
|
||||
})
|
||||
},
|
||||
function() {
|
||||
classNames.forEach(function (className) {
|
||||
targetElt.classList.add(className)
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
loadingStateEltsByType['data-loading-disable'].forEach(
|
||||
(sourceElt) => {
|
||||
getLoadingTarget(sourceElt).forEach((targetElt) => {
|
||||
function (sourceElt) {
|
||||
getLoadingTarget(sourceElt).forEach(function (targetElt) {
|
||||
queueLoadingState(
|
||||
sourceElt,
|
||||
targetElt,
|
||||
() => (targetElt.disabled = true),
|
||||
() => (targetElt.disabled = false)
|
||||
function() { targetElt.disabled = true },
|
||||
function() { targetElt.disabled = false }
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
loadingStateEltsByType['data-loading-aria-busy'].forEach(
|
||||
(sourceElt) => {
|
||||
getLoadingTarget(sourceElt).forEach((targetElt) => {
|
||||
function (sourceElt) {
|
||||
getLoadingTarget(sourceElt).forEach(function (targetElt) {
|
||||
queueLoadingState(
|
||||
sourceElt,
|
||||
targetElt,
|
||||
() => (targetElt.setAttribute("aria-busy", "true")),
|
||||
() => (targetElt.removeAttribute("aria-busy"))
|
||||
function () { targetElt.setAttribute("aria-busy", "true") },
|
||||
function () { targetElt.removeAttribute("aria-busy") }
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ htmx.defineExtension('morphdom-swap', {
|
||||
handleSwap: function (swapStyle, target, fragment) {
|
||||
if (swapStyle === 'morphdom') {
|
||||
if (fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
||||
morphdom(target, fragment.firstElementChild);
|
||||
// IE11 doesn't support DocumentFragment.firstElementChild
|
||||
morphdom(target, fragment.firstElementChild || fragment.firstChild);
|
||||
return [target];
|
||||
} else {
|
||||
morphdom(target, fragment.outerHTML);
|
||||
|
62
src/htmx.js
62
src/htmx.js
@ -573,9 +573,17 @@ return (function () {
|
||||
}
|
||||
}
|
||||
|
||||
function startsWith(str, prefix) {
|
||||
return str.substring(0, prefix.length) === prefix
|
||||
}
|
||||
|
||||
function endsWith(str, suffix) {
|
||||
return str.substring(str.length - suffix.length) === suffix
|
||||
}
|
||||
|
||||
function normalizeSelector(selector) {
|
||||
var trimmedSelector = selector.trim();
|
||||
if (trimmedSelector.startsWith("<") && trimmedSelector.endsWith("/>")) {
|
||||
if (startsWith(trimmedSelector, "<") && endsWith(trimmedSelector, "/>")) {
|
||||
return trimmedSelector.substring(1, trimmedSelector.length - 2);
|
||||
} else {
|
||||
return trimmedSelector;
|
||||
@ -1864,12 +1872,25 @@ return (function () {
|
||||
}
|
||||
|
||||
function findHxOnWildcardElements(elt) {
|
||||
if (!document.evaluate) return []
|
||||
var node = null
|
||||
var elements = []
|
||||
|
||||
if (document.evaluate) {
|
||||
var iter = document.evaluate('//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") ]]', elt)
|
||||
while (node = iter.iterateNext()) elements.push(node)
|
||||
} else {
|
||||
var allElements = document.getElementsByTagName("*")
|
||||
for (var i = 0; i < allElements.length; i++) {
|
||||
var attributes = allElements[i].attributes
|
||||
for (var j = 0; j < attributes.length; j++) {
|
||||
var attrName = attributes[j].name
|
||||
if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:")) {
|
||||
elements.push(allElements[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let node = null
|
||||
const elements = []
|
||||
const iter = document.evaluate('//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") ]]', elt)
|
||||
while (node = iter.iterateNext()) elements.push(node)
|
||||
return elements
|
||||
}
|
||||
|
||||
@ -1975,10 +1996,10 @@ return (function () {
|
||||
for (var i = 0; i < elt.attributes.length; i++) {
|
||||
var name = elt.attributes[i].name
|
||||
var value = elt.attributes[i].value
|
||||
if (name.startsWith("hx-on:") || name.startsWith("data-hx-on:")) {
|
||||
if (startsWith(name, "hx-on:") || startsWith(name, "data-hx-on:")) {
|
||||
let eventName = name.slice(name.indexOf(":") + 1)
|
||||
// if the eventName starts with a colon, prepend "htmx" for shorthand support
|
||||
if (eventName.startsWith(":")) eventName = "htmx" + eventName
|
||||
if (startsWith(eventName, ":")) eventName = "htmx" + eventName
|
||||
|
||||
addHxOnEventHandler(elt, eventName, value)
|
||||
}
|
||||
@ -2207,7 +2228,13 @@ return (function () {
|
||||
// so we can prevent privileged data entering the cache.
|
||||
// The page will still be reachable as a history entry, but htmx will fetch it
|
||||
// live from the server onpopstate rather than look in the localStorage cache
|
||||
var disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]');
|
||||
var disableHistoryCache
|
||||
try {
|
||||
disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]')
|
||||
} catch (e) {
|
||||
// IE11: insensitive modifier not supported so fallback to case sensitive selector
|
||||
disableHistoryCache = getDocument().querySelector('[hx-history="false"],[data-hx-history="false"]')
|
||||
}
|
||||
if (!disableHistoryCache) {
|
||||
triggerEvent(getDocument().body, "htmx:beforeHistorySave", {path: path, historyElt: elt});
|
||||
saveToHistoryCache(path, cleanInnerHtmlForHistory(elt), getDocument().title, window.scrollY);
|
||||
@ -2220,7 +2247,7 @@ return (function () {
|
||||
// remove the cache buster parameter, if any
|
||||
if (htmx.config.getCacheBusterParam) {
|
||||
path = path.replace(/org\.htmx\.cache-buster=[^&]*&?/, '')
|
||||
if (path.endsWith('&') || path.endsWith("?")) {
|
||||
if (endsWith(path, '&') || endsWith(path, "?")) {
|
||||
path = path.slice(0, -1);
|
||||
}
|
||||
}
|
||||
@ -2856,9 +2883,18 @@ return (function () {
|
||||
}
|
||||
|
||||
function verifyPath(elt, path, requestConfig) {
|
||||
var url = new URL(path, document.location.href);
|
||||
var origin = document.location.origin;
|
||||
var sameHost = origin === url.origin;
|
||||
var sameHost
|
||||
var url
|
||||
if (typeof URL === "function") {
|
||||
url = new URL(path, document.location.href);
|
||||
var origin = document.location.origin;
|
||||
sameHost = origin === url.origin;
|
||||
} else {
|
||||
// IE11 doesn't support URL
|
||||
url = path
|
||||
sameHost = startsWith(path, document.location.origin)
|
||||
}
|
||||
|
||||
if (htmx.config.selfRequestsOnly) {
|
||||
if (!sameHost) {
|
||||
return false;
|
||||
|
@ -18,12 +18,13 @@ describe("hx-disinherit attribute", function() {
|
||||
var btn = byId("bx1");
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerHTML.should.equal(response_inner);
|
||||
btn.firstChild.id.should.equal("snowflake");
|
||||
btn.innerText.should.equal("Hello world");
|
||||
})
|
||||
|
||||
|
||||
it('disinherit exclude single attribute', function () {
|
||||
var response_inner = '<div id="snowflake" class="">Hello world</div>'
|
||||
var response_inner = '<div id="snowflake">Hello world</div>'
|
||||
var response = '<div id="unique">' + response_inner + '</div>'
|
||||
this.server.respondWith("GET", "/test", response);
|
||||
|
||||
@ -31,7 +32,9 @@ describe("hx-disinherit attribute", function() {
|
||||
var btn = byId("bx1");
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerHTML.should.equal(response + '<span id="cta" class="">Click Me!</span>');
|
||||
btn.firstChild.id.should.equal("unique")
|
||||
btn.firstChild.firstChild.id.should.equal("snowflake")
|
||||
btn.childNodes[1].innerText.should.equal("Click Me!")
|
||||
});
|
||||
|
||||
it('disinherit exclude multiple attributes', function () {
|
||||
@ -47,7 +50,9 @@ describe("hx-disinherit attribute", function() {
|
||||
this.server.respond();
|
||||
console.log(btn.innerHTML);
|
||||
console.log(response);
|
||||
btn.innerHTML.should.equal('<span id="cta" class="">' + response + '</span>');
|
||||
btn.firstChild.id.should.equal("cta")
|
||||
btn.firstChild.firstChild.id.should.equal("unique")
|
||||
btn.firstChild.firstChild.firstChild.id.should.equal("snowflake")
|
||||
});
|
||||
|
||||
it('disinherit exclude all attributes', function () {
|
||||
@ -62,7 +67,8 @@ describe("hx-disinherit attribute", function() {
|
||||
var btn = byId("bx1");
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerHTML.should.equal(response);
|
||||
btn.firstChild.id.should.equal("unique");
|
||||
btn.firstChild.firstChild.id.should.equal("snowflake");
|
||||
});
|
||||
|
||||
it('same-element inheritance disable', function () {
|
||||
@ -73,7 +79,8 @@ describe("hx-disinherit attribute", function() {
|
||||
var btn = make('<button hx-select="#snowflake" hx-target="#container" hx-trigger="click" hx-get="/test" hx-swap="outerHTML" hx-disinherit="*"><div id="container"></div></button>')
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerHTML.should.equal(response_inner);
|
||||
btn.firstChild.id.should.equal("snowflake");
|
||||
btn.firstChild.innerText.should.equal("Hello world");
|
||||
});
|
||||
|
||||
it('same-element inheritance disable with child nodes', function () {
|
||||
@ -86,7 +93,8 @@ describe("hx-disinherit attribute", function() {
|
||||
var btn = byId("bx1");
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerHTML.should.equal('<div id="target" class="">unique-snowflake</div>');
|
||||
btn.firstChild.id.should.equal('target');
|
||||
btn.firstChild.innerText.should.equal('unique-snowflake');
|
||||
var count = (div.parentElement.innerHTML.match(/snowflake/g) || []).length;
|
||||
count.should.equal(2); // hx-select of parent div and newly loaded inner content
|
||||
});
|
||||
|
@ -841,7 +841,9 @@ describe("Core htmx AJAX Tests", function(){
|
||||
var btn = make('<button hx-get="/test">Click Me!</button>')
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerText.should.equal("Clicked!");
|
||||
if (supportsSvgTitles()) { // IE 11
|
||||
btn.innerText.should.equal("Clicked!");
|
||||
}
|
||||
window.document.title.should.equal(originalTitle);
|
||||
});
|
||||
|
||||
@ -855,7 +857,9 @@ describe("Core htmx AJAX Tests", function(){
|
||||
var btn = make('<button hx-get="/test">Click Me!</button>')
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
btn.innerText.should.equal("Clicked!");
|
||||
if (supportsSvgTitles()) { // IE 11
|
||||
btn.innerText.should.equal("Clicked!");
|
||||
}
|
||||
window.document.title.should.equal(newTitle);
|
||||
});
|
||||
|
||||
@ -1058,6 +1062,11 @@ describe("Core htmx AJAX Tests", function(){
|
||||
})
|
||||
|
||||
it('properly handles clicked submit button with a value outside a htmx form', function () {
|
||||
if (!supportsFormAttribute()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support form attribute"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
var values;
|
||||
this.server.respondWith("Post", "/test", function (xhr) {
|
||||
values = getParameters(xhr);
|
||||
@ -1075,6 +1084,11 @@ describe("Core htmx AJAX Tests", function(){
|
||||
})
|
||||
|
||||
it('properly handles clicked submit input with a value outside a htmx form', function () {
|
||||
if (!supportsFormAttribute()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support form attribute"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
var values;
|
||||
this.server.respondWith("Post", "/test", function (xhr) {
|
||||
values = getParameters(xhr);
|
||||
@ -1146,6 +1160,11 @@ describe("Core htmx AJAX Tests", function(){
|
||||
})
|
||||
|
||||
it('properly handles clicked submit button with a value inside a form, referencing another form', function () {
|
||||
if (!supportsFormAttribute()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support form attribute"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
var values;
|
||||
this.server.respondWith("Post", "/test", function (xhr) {
|
||||
values = getParameters(xhr);
|
||||
@ -1166,6 +1185,11 @@ describe("Core htmx AJAX Tests", function(){
|
||||
})
|
||||
|
||||
it('properly handles clicked submit input with a value inside a form, referencing another form', function () {
|
||||
if (!supportsFormAttribute()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support form attribute"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
var values;
|
||||
this.server.respondWith("Post", "/test", function (xhr) {
|
||||
values = getParameters(xhr);
|
||||
|
@ -116,8 +116,14 @@ describe("Core htmx Events", function() {
|
||||
});
|
||||
|
||||
it("htmx:configRequest on form gives access to submit event", function () {
|
||||
var skip = false
|
||||
var submitterId;
|
||||
var handler = htmx.on("htmx:configRequest", function (evt) {
|
||||
// submitter may be null, but undefined means the browser doesn't support it
|
||||
if (typeof evt.detail.triggeringEvent.submitter === "undefined") {
|
||||
skip = true
|
||||
return
|
||||
}
|
||||
evt.detail.headers['X-Submitter-Id'] = evt.detail.triggeringEvent.submitter.id;
|
||||
});
|
||||
try {
|
||||
@ -129,6 +135,10 @@ describe("Core htmx Events", function() {
|
||||
var btn = byId('b1');
|
||||
btn.click();
|
||||
this.server.respond();
|
||||
if (skip) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support submitter"
|
||||
this.skip()
|
||||
}
|
||||
should.equal(submitterId, "b1")
|
||||
} finally {
|
||||
htmx.off("htmx:configRequest", handler);
|
||||
@ -379,6 +389,12 @@ describe("Core htmx Events", function() {
|
||||
});
|
||||
|
||||
it("htmx:sendError is called after a failed request", function (done) {
|
||||
if (IsIE11()) {
|
||||
// IE will throw an exception on xhr.open with the URL below, xhr.send won't even be called
|
||||
this._runnable.title += " - Skipped on IE11 as xhr.send won't even be called with a file URL"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
var called = false;
|
||||
var handler = htmx.on("htmx:sendError", function (evt) {
|
||||
called = true;
|
||||
|
@ -22,7 +22,11 @@ describe("Core htmx internals Tests", function() {
|
||||
})
|
||||
|
||||
it("makeFragment works with template wrapping", function(){
|
||||
htmx.config.useTemplateFragments = true;
|
||||
if (!supportsTemplates()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support templates"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
try {
|
||||
htmx._("makeFragment")("<html></html>").children.length.should.equal(0);
|
||||
htmx._("makeFragment")("<html><body></body></html>").children.length.should.equal(0);
|
||||
@ -46,6 +50,11 @@ describe("Core htmx internals Tests", function() {
|
||||
|
||||
|
||||
it("makeFragment works with template wrapping and funky combos", function(){
|
||||
if (!supportsTemplates()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support templates"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
htmx.config.useTemplateFragments = true;
|
||||
try {
|
||||
var fragment = htmx._("makeFragment")("<td></td><div></div>");
|
||||
|
@ -49,10 +49,14 @@ describe("Core htmx perf Tests", function() {
|
||||
})
|
||||
|
||||
it("history snapshot cleaning should be fast", function(){
|
||||
//
|
||||
var size = 5 * 1024 // ~350K in size, about the size of CNN's body tag :p
|
||||
if (IsIE11()) {
|
||||
// So slow in IE11 it freezes the browser and blocks other tests, pretty annoying
|
||||
size = 5 * 100 // Seriously this already takes ~1.5 SECOND to run, more simply makes it crash
|
||||
}
|
||||
var workArea = getWorkArea();
|
||||
var html = "<div class='foo bar'>Yay, really large HTML documents are fun!</div>\n";
|
||||
html = stringRepeat(html, 5 * 1024); // ~350K in size, about the size of CNN's body tag :p
|
||||
html = stringRepeat(html, size);
|
||||
workArea.insertAdjacentHTML("beforeend", html)
|
||||
var start = performance.now();
|
||||
htmx._("cleanInnerHtmlForHistory")(workArea);
|
||||
|
@ -129,6 +129,12 @@ describe("Core htmx Regression Tests", function(){
|
||||
})
|
||||
|
||||
it('a form can reset based on the htmx:afterRequest event', function() {
|
||||
if (IsIE11()) {
|
||||
this._runnable.title += " - Skipped as hyperscript isn't IE11 compatible"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
|
||||
this.server.respondWith("POST", "/test", "posted");
|
||||
|
||||
var form = make('<div id="d1"></div><form _="on htmx:afterRequest reset() me" hx-post="/test" hx-target="#d1">' +
|
||||
|
@ -110,6 +110,12 @@ describe("Core htmx client side validation tests", function(){
|
||||
|
||||
it('hyperscript validation error prevents request', function()
|
||||
{
|
||||
if (IsIE11()) {
|
||||
this._runnable.title += " - Skipped as hyperscript isn't IE11 compatible"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
|
||||
this.server.respondWith("POST", "/test", "Clicked!");
|
||||
|
||||
var form = make('<form hx-post="/test" hx-trigger="click">' +
|
||||
|
@ -2,6 +2,11 @@ describe("hyperscript integration", function() {
|
||||
beforeEach(function () {
|
||||
this.server = makeServer();
|
||||
clearWorkArea();
|
||||
|
||||
if (IsIE11()) {
|
||||
this.title += " - Skipped as hyperscript isn't IE11 compatible"
|
||||
this.skip()
|
||||
}
|
||||
});
|
||||
afterEach(function () {
|
||||
this.server.restore();
|
||||
|
@ -1,7 +1,84 @@
|
||||
describe("web-sockets extension", function () {
|
||||
// mock-socket isn't IE11 compatible, thus this handmade one
|
||||
// Using the same syntax as the library, so the initial tests didn't require changes to work
|
||||
// TODO when we get rid of IE11 for htmx2, replace this by mock-socket since it ofc doesn't implement every feature
|
||||
function mockWebsocket() {
|
||||
var mockSocketClient = {
|
||||
addEventListener: function (event, handler) {
|
||||
var handlers = this._listeners[event] || []
|
||||
handlers.push(handler)
|
||||
this._listeners[event] = handlers
|
||||
},
|
||||
on: function (event, handler) {
|
||||
this.addEventListener(event, handler)
|
||||
},
|
||||
send: function (data) {
|
||||
mockSocketServer._fireEvent("message", data)
|
||||
},
|
||||
connect: function () {
|
||||
this._open = true
|
||||
mockSocketServer._fireEvent("connection", mockSocketServer)
|
||||
setTimeout(function () {
|
||||
this._fireEvent("open", {type: "open"})
|
||||
}.bind(this), 2)
|
||||
},
|
||||
close: function () {
|
||||
if (this._open) {
|
||||
this._open = false
|
||||
this._fireEvent("close", {type: "close", code: 0})
|
||||
}
|
||||
},
|
||||
_listeners: {},
|
||||
_fireEvent: function (event, data) {
|
||||
var handlers = this._listeners[event] || []
|
||||
if (typeof this["on" + event] === "function") {
|
||||
handlers.push(this["on" + event])
|
||||
}
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
handlers[i](data)
|
||||
}
|
||||
},
|
||||
_open: false,
|
||||
}
|
||||
var mockSocketServer = {
|
||||
addEventListener: function (event, handler) {
|
||||
var handlers = this._listeners[event] || []
|
||||
handlers.push(handler)
|
||||
this._listeners[event] = handlers
|
||||
},
|
||||
on: function (event, handler) {
|
||||
this.addEventListener(event, handler)
|
||||
},
|
||||
close: function () {
|
||||
mockSocketClient.close()
|
||||
},
|
||||
stop: function () {
|
||||
},
|
||||
emit: function (event, data) {
|
||||
mockSocketClient._fireEvent(event, {data: data})
|
||||
},
|
||||
clients: function () { // Replicate old mock-socket syntax to avoid huge file diff to merge
|
||||
return mockSocketClient._open ? [1] : []
|
||||
},
|
||||
_listeners: {},
|
||||
_fireEvent: function (event, data) {
|
||||
var handlers = this._listeners[event] || []
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
handlers[i](data)
|
||||
}
|
||||
},
|
||||
}
|
||||
return {
|
||||
client: mockSocketClient,
|
||||
server: mockSocketServer,
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
this.server = makeServer();
|
||||
this.socketServer = new Mock.Server('ws://localhost:8080');
|
||||
// this.socketServer = new Mock.Server('ws://localhost:8080');
|
||||
var mockedSocket = mockWebsocket();
|
||||
this.socketServer = mockedSocket.server;
|
||||
this.messages = [];
|
||||
this.clock = sinon.useFakeTimers();
|
||||
|
||||
@ -19,12 +96,19 @@ describe("web-sockets extension", function () {
|
||||
}
|
||||
|
||||
clearWorkArea();
|
||||
this.oldCreateWebSocket = htmx.createWebSocket;
|
||||
htmx.createWebSocket = function () {
|
||||
mockedSocket.client.connect()
|
||||
return mockedSocket.client
|
||||
};
|
||||
});
|
||||
afterEach(function () {
|
||||
this.server.restore();
|
||||
clearWorkArea();
|
||||
this.socketServer.close();
|
||||
this.socketServer.stop();
|
||||
this.clock.restore();
|
||||
htmx.createWebSocket = this.oldCreateWebSocket;
|
||||
});
|
||||
|
||||
it('can establish connection with the server', function () {
|
||||
@ -454,6 +538,12 @@ describe("web-sockets extension", function () {
|
||||
})
|
||||
|
||||
it('sends data to the server with external non-htmx form + submit button & value', function () {
|
||||
if (!supportsFormAttribute()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support form attribute"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
|
||||
make('<div hx-ext="ws" ws-connect="ws://localhost:8080">' +
|
||||
'<form ws-send id="form">' +
|
||||
'<input type="hidden" name="foo" value="bar">' +
|
||||
@ -481,6 +571,12 @@ describe("web-sockets extension", function () {
|
||||
})
|
||||
|
||||
it('sends data to the server with external non-htmx form + submit input & value', function () {
|
||||
if (!supportsFormAttribute()) {
|
||||
this._runnable.title += " - Skipped as IE11 doesn't support form attribute"
|
||||
this.skip()
|
||||
return
|
||||
}
|
||||
|
||||
make('<div hx-ext="ws" ws-connect="ws://localhost:8080">' +
|
||||
'<form ws-send id="form">' +
|
||||
'<input type="hidden" name="foo" value="bar">' +
|
||||
|
@ -160,6 +160,7 @@
|
||||
<div id="mocha"></div>
|
||||
|
||||
<script class="mocha-exec">
|
||||
mocha.setup({globals: ['$0', '$1', '$2', '$3', '$4', 'performance', 'requestAnimationFrame', 'cancelAnimationFrame']}); <!-- IE11 -->
|
||||
mocha.run();
|
||||
</script>
|
||||
<em>Work Area</em>
|
||||
|
@ -5,6 +5,7 @@ function byId(id) {
|
||||
}
|
||||
|
||||
function make(htmlStr) {
|
||||
htmlStr = htmlStr.trim()
|
||||
var makeFn = function () {
|
||||
var range = document.createRange();
|
||||
var fragment = range.createContextualFragment(htmlStr);
|
||||
@ -38,7 +39,7 @@ function getWorkArea() {
|
||||
}
|
||||
|
||||
function clearWorkArea() {
|
||||
const workArea = getWorkArea();
|
||||
var workArea = getWorkArea();
|
||||
if (workArea) workArea.innerHTML = "";
|
||||
}
|
||||
|
||||
@ -107,3 +108,33 @@ function log(val) {
|
||||
console.log(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// region IE11
|
||||
function supportsTemplates() {
|
||||
return typeof document.createElement("template").content !== "undefined"
|
||||
}
|
||||
|
||||
function supportsSvgTitles() {
|
||||
// Need to append the element to the body, otherwise innerText will add the svg title to the returned value...
|
||||
var tempButton = document.createElement("button")
|
||||
tempButton.innerHTML = '<svg><title>Svg title</title></svg>Text';
|
||||
document.body.appendChild(tempButton)
|
||||
var titleOk = tempButton.innerText === "Text"
|
||||
document.body.removeChild(tempButton)
|
||||
return titleOk
|
||||
}
|
||||
|
||||
function supportsFormAttribute() {
|
||||
var parser = new DOMParser()
|
||||
return !!parser.parseFromString('<button form="form"></button><form id="form"></form>', "text/html").body.firstChild.form
|
||||
}
|
||||
|
||||
function supportsXPath() {
|
||||
return typeof document.evaluate !== "undefined"
|
||||
}
|
||||
|
||||
function IsIE11() {
|
||||
return !supportsTemplates() && !supportsSvgTitles() && !supportsFormAttribute() && !supportsXPath()
|
||||
}
|
||||
|
||||
// endregion
|
Loading…
x
Reference in New Issue
Block a user