mirror of
https://github.com/vale981/tridactyl
synced 2025-03-05 09:31:41 -05:00
Merge remote-tracking branch 'origin/master' into HEAD
This commit is contained in:
commit
0693cdc45d
9 changed files with 1359 additions and 31 deletions
924
package-lock.json
generated
924
package-lock.json
generated
|
@ -1388,6 +1388,7 @@
|
|||
"requires": {
|
||||
"anymatch": "1.3.2",
|
||||
"async-each": "1.0.1",
|
||||
"fsevents": "1.1.3",
|
||||
"glob-parent": "2.0.0",
|
||||
"inherits": "2.0.3",
|
||||
"is-binary-path": "1.0.1",
|
||||
|
@ -3053,6 +3054,910 @@
|
|||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
|
||||
"integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"nan": "2.7.0",
|
||||
"node-pre-gyp": "0.6.39"
|
||||
},
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "4.11.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"co": "4.6.0",
|
||||
"json-stable-stringify": "1.0.1"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delegates": "1.0.0",
|
||||
"readable-stream": "2.2.9"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "0.2.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.6.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "0.4.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"block-stream": {
|
||||
"version": "0.0.9",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"boom": {
|
||||
"version": "2.10.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.7",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "0.4.2",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"buffer-shims": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"cryptiles": {
|
||||
"version": "2.0.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boom": "2.10.1"
|
||||
}
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.4.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsbn": "0.1.1"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.1.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"asynckit": "0.4.0",
|
||||
"combined-stream": "1.0.5",
|
||||
"mime-types": "2.1.15"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"fstream": {
|
||||
"version": "1.0.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11",
|
||||
"inherits": "2.0.3",
|
||||
"mkdirp": "0.5.1",
|
||||
"rimraf": "2.6.1"
|
||||
}
|
||||
},
|
||||
"fstream-ignore": {
|
||||
"version": "1.0.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fstream": "1.0.11",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4"
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"aproba": "1.1.1",
|
||||
"console-control-strings": "1.1.0",
|
||||
"has-unicode": "2.0.1",
|
||||
"object-assign": "4.1.1",
|
||||
"signal-exit": "3.0.2",
|
||||
"string-width": "1.0.2",
|
||||
"strip-ansi": "3.0.1",
|
||||
"wide-align": "1.1.2"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "1.0.0",
|
||||
"inflight": "1.0.6",
|
||||
"inherits": "2.0.3",
|
||||
"minimatch": "3.0.4",
|
||||
"once": "1.4.0",
|
||||
"path-is-absolute": "1.0.1"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.1.11",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "1.0.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "4.2.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ajv": "4.11.8",
|
||||
"har-schema": "1.0.5"
|
||||
}
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"hawk": {
|
||||
"version": "3.1.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"boom": "2.10.1",
|
||||
"cryptiles": "2.0.5",
|
||||
"hoek": "2.16.3",
|
||||
"sntp": "1.0.9"
|
||||
}
|
||||
},
|
||||
"hoek": {
|
||||
"version": "2.16.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "0.2.0",
|
||||
"jsprim": "1.4.0",
|
||||
"sshpk": "1.13.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "1.4.0",
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "1.0.1"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"jodid25519": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsbn": "0.1.1"
|
||||
}
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json-stable-stringify": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"jsonify": "0.0.0"
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"jsonify": {
|
||||
"version": "0.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.0.2",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.27.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.15",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.27.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.6.39",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"detect-libc": "1.0.2",
|
||||
"hawk": "3.1.3",
|
||||
"mkdirp": "0.5.1",
|
||||
"nopt": "4.0.1",
|
||||
"npmlog": "4.1.0",
|
||||
"rc": "1.2.1",
|
||||
"request": "2.81.0",
|
||||
"rimraf": "2.6.1",
|
||||
"semver": "5.3.0",
|
||||
"tar": "2.2.1",
|
||||
"tar-pack": "3.4.0"
|
||||
}
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"abbrev": "1.1.0",
|
||||
"osenv": "0.1.4"
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"are-we-there-yet": "1.1.4",
|
||||
"console-control-strings": "1.1.0",
|
||||
"gauge": "2.7.4",
|
||||
"set-blocking": "2.0.0"
|
||||
}
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.8.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"os-homedir": "1.0.2",
|
||||
"os-tmpdir": "1.0.2"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "0.2.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"deep-extend": "0.4.2",
|
||||
"ini": "1.3.4",
|
||||
"minimist": "1.2.0",
|
||||
"strip-json-comments": "2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.2.9",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-shims": "1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"string_decoder": "1.0.1",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.81.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"aws-sign2": "0.6.0",
|
||||
"aws4": "1.6.0",
|
||||
"caseless": "0.12.0",
|
||||
"combined-stream": "1.0.5",
|
||||
"extend": "3.0.1",
|
||||
"forever-agent": "0.6.1",
|
||||
"form-data": "2.1.4",
|
||||
"har-validator": "4.2.1",
|
||||
"hawk": "3.1.3",
|
||||
"http-signature": "1.1.1",
|
||||
"is-typedarray": "1.0.0",
|
||||
"isstream": "0.1.2",
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"mime-types": "2.1.15",
|
||||
"oauth-sign": "0.8.2",
|
||||
"performance-now": "0.2.0",
|
||||
"qs": "6.4.0",
|
||||
"safe-buffer": "5.0.1",
|
||||
"stringstream": "0.0.5",
|
||||
"tough-cookie": "2.3.2",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"uuid": "3.0.1"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "7.1.2"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.3.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"sntp": {
|
||||
"version": "1.0.9",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "2.16.3"
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.13.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"asn1": "0.2.3",
|
||||
"assert-plus": "1.0.0",
|
||||
"bcrypt-pbkdf": "1.0.1",
|
||||
"dashdash": "1.14.1",
|
||||
"ecc-jsbn": "0.1.1",
|
||||
"getpass": "0.1.7",
|
||||
"jodid25519": "1.0.2",
|
||||
"jsbn": "0.1.1",
|
||||
"tweetnacl": "0.14.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "1.1.0",
|
||||
"is-fullwidth-code-point": "1.0.0",
|
||||
"strip-ansi": "3.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.0.1"
|
||||
}
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "2.1.1"
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "2.2.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"block-stream": "0.0.9",
|
||||
"fstream": "1.0.11",
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"tar-pack": {
|
||||
"version": "3.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"debug": "2.6.8",
|
||||
"fstream": "1.0.11",
|
||||
"fstream-ignore": "1.0.5",
|
||||
"once": "1.4.0",
|
||||
"readable-stream": "2.2.9",
|
||||
"rimraf": "2.6.1",
|
||||
"tar": "2.2.1",
|
||||
"uid-number": "0.0.6"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.3.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"punycode": "1.4.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"uid-number": {
|
||||
"version": "0.0.6",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.3.6",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"extsprintf": "1.0.2"
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"string-width": "1.0.2"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"fuse.js": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.2.0.tgz",
|
||||
|
@ -4975,12 +5880,6 @@
|
|||
"integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.clone": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
|
||||
"integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.defaults": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
|
||||
|
@ -6609,6 +7508,7 @@
|
|||
"anymatch": "1.3.2",
|
||||
"exec-sh": "0.2.1",
|
||||
"fb-watchman": "2.0.0",
|
||||
"fsevents": "1.1.3",
|
||||
"minimatch": "3.0.4",
|
||||
"minimist": "1.2.0",
|
||||
"walker": "1.0.7",
|
||||
|
@ -8030,16 +8930,6 @@
|
|||
"integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=",
|
||||
"dev": true
|
||||
},
|
||||
"typedoc-webpack-plugin": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/typedoc-webpack-plugin/-/typedoc-webpack-plugin-1.1.4.tgz",
|
||||
"integrity": "sha1-XTv8bYJKUvQBCe6J0r+8pfGsMKE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash.clone": "4.5.0",
|
||||
"lodash.merge": "4.6.0"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.3.tgz",
|
||||
|
@ -8617,7 +9507,7 @@
|
|||
}
|
||||
},
|
||||
"web-ext-types": {
|
||||
"version": "github:kelseasy/web-ext-types#30d79e893b7a30d3fbfd8aa0affedaa8dca0d211",
|
||||
"version": "github:kelseasy/web-ext-types#417d6ddcd76d8a05d7e2222aec3544e01637785b",
|
||||
"dev": true
|
||||
},
|
||||
"webidl-conversions": {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"ts-jest": "^21.1.3",
|
||||
"ts-node": "^3.3.0",
|
||||
"typedoc": "^0.9.0",
|
||||
"typedoc-webpack-plugin": "^1.1.4",
|
||||
"typescript": "^2.5.3",
|
||||
"uglify-es": "^3.1.5",
|
||||
"uglifyjs-webpack-plugin": "^1.0.0-rc.0",
|
||||
|
|
|
@ -14,7 +14,7 @@ Remember that tridactyl cannot run on any page on addons.mozilla.org, about:\*,
|
|||
|
||||
## Highlighted features:
|
||||
|
||||
- Press `b` to bring up a list of open tabs in the current window; you can type the tab ID or part of the title or URL to choose a tab (the buffer list doesn't show which one you've selected yet, but it does work)
|
||||
- Press `b` to bring up a list of open tabs in the current window; you can type the tab ID or part of the title or URL to choose a tab
|
||||
- Press `I` to enter ignore mode. `Shift` + `Escape` to return to normal mode.
|
||||
- Press `f` to start "hint mode", `F` to open in background
|
||||
- Press `o` to `:open` a different page
|
||||
|
|
|
@ -107,11 +107,47 @@ clInput.addEventListener("keydown", function (keyevent) {
|
|||
history(1)
|
||||
break
|
||||
|
||||
// Clear input on ^C
|
||||
case "a":
|
||||
if (keyevent.ctrlKey) {
|
||||
keyevent.preventDefault()
|
||||
keyevent.stopPropagation()
|
||||
setCursor()
|
||||
}
|
||||
break
|
||||
|
||||
case "e":
|
||||
if (keyevent.ctrlKey){
|
||||
keyevent.preventDefault()
|
||||
keyevent.stopPropagation()
|
||||
setCursor(clInput.value.length)
|
||||
}
|
||||
break
|
||||
|
||||
case "u":
|
||||
if (keyevent.ctrlKey){
|
||||
keyevent.preventDefault()
|
||||
keyevent.stopPropagation()
|
||||
clInput.value = clInput.value.slice(clInput.selectionStart, clInput.value.length)
|
||||
setCursor()
|
||||
}
|
||||
break
|
||||
|
||||
case "k":
|
||||
if (keyevent.ctrlKey){
|
||||
keyevent.preventDefault()
|
||||
keyevent.stopPropagation()
|
||||
clInput.value = clInput.value.slice(0, clInput.selectionStart)
|
||||
}
|
||||
break
|
||||
|
||||
// Clear input on ^C if there is no selection
|
||||
// Todo: hard mode: vi style editing on cli, like set -o mode vi
|
||||
// should probably just defer to another library
|
||||
case "c":
|
||||
if (keyevent.ctrlKey) hide_and_clear()
|
||||
if (keyevent.ctrlKey &&
|
||||
! clInput.value.substring(clInput.selectionStart, clInput.selectionEnd)) {
|
||||
hide_and_clear()
|
||||
}
|
||||
break
|
||||
|
||||
case "f":
|
||||
|
@ -178,6 +214,10 @@ async function hide_and_clear(){
|
|||
isVisible = false
|
||||
}
|
||||
|
||||
function setCursor(n = 0) {
|
||||
clInput.setSelectionRange(n, n, "none")
|
||||
}
|
||||
|
||||
function tabcomplete(){
|
||||
let fragment = clInput.value
|
||||
let matches = state.cmdHistory.filter((key)=>key.startsWith(fragment))
|
||||
|
|
|
@ -66,7 +66,6 @@ const DEFAULTS = o({
|
|||
"s": "fillcmdline open search",
|
||||
"S": "fillcmdline tabopen search",
|
||||
"M": "gobble 1 quickmark",
|
||||
"xx": "something",
|
||||
// "B": "fillcmdline bufferall",
|
||||
"b": "fillcmdline buffer",
|
||||
"ZZ": "qall",
|
||||
|
|
|
@ -12,9 +12,11 @@ import {MsgSafeNode} from './msgsafe'
|
|||
*/
|
||||
export function isTextEditable (element: MsgSafeNode) {
|
||||
if (element) {
|
||||
switch (element.nodeName) {
|
||||
// HTML is always upper case, but XHTML is not necessarily upper case
|
||||
switch (element.nodeName.toUpperCase()) {
|
||||
case 'INPUT':
|
||||
return isEditableHTMLInput(element)
|
||||
case 'SELECT':
|
||||
case 'TEXTAREA':
|
||||
case 'OBJECT':
|
||||
return true
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
The default keybinds can be found [here](/static/docs/modules/_config_.html#defaults)
|
||||
|
||||
Tridactyl is in a pretty early stage of development. Please report any
|
||||
issues and make requests for missing features on the GitHub [project page](1).
|
||||
issues and make requests for missing features on the GitHub [project page][1].
|
||||
You can also get in touch using Matrix, Gitter, or IRC chat clients:
|
||||
|
||||
[![Matrix Chat][matrix-badge]][matrix-link]
|
||||
|
@ -19,8 +19,7 @@
|
|||
## Highlighted features:
|
||||
|
||||
- Press `b` to bring up a list of open tabs in the current window; you can
|
||||
type the tab ID or part of the title or URL to choose a tab (the buffer
|
||||
list doesn't show which one you've selected yet, but it does work)
|
||||
type the tab ID or part of the title or URL to choose a tab
|
||||
- Press `I` to enter ignore mode. `Shift` + `Escape` to return to normal
|
||||
mode.
|
||||
- Press `f` to start "hint mode", `F` to open in background
|
||||
|
@ -88,7 +87,7 @@ import * as keydown from "./keydown_background"
|
|||
//#background_helper
|
||||
import {activeTab, activeTabId, firefoxVersionAtLeast} from './lib/webext'
|
||||
//#content_helper
|
||||
import {incrementUrl, getUrlRoot, getUrlParent} from "./url_util"
|
||||
import * as UrlUtil from "./url_util"
|
||||
//#background_helper
|
||||
import * as CommandLineBackground from './commandline_background'
|
||||
//#content_helper
|
||||
|
@ -273,7 +272,7 @@ export async function reload(n = 1, hard = false) {
|
|||
/** Reloads all tabs, bypassing the cache if hard is set to true */
|
||||
//#background
|
||||
export async function reloadall(hard = false){
|
||||
let tabs = await browser.tabs.query({})
|
||||
let tabs = await browser.tabs.query({currentWindow: true})
|
||||
let reloadprops = {bypassCache: hard}
|
||||
tabs.map(tab => browser.tabs.reload(tab.id, reloadprops))
|
||||
}
|
||||
|
@ -396,7 +395,7 @@ export function followpage(rel: 'next'|'prev' = 'next') {
|
|||
*/
|
||||
//#content
|
||||
export function urlincrement(count = 1){
|
||||
let newUrl = incrementUrl(window.location.href, count)
|
||||
let newUrl = UrlUtil.incrementUrl(window.location.href, count)
|
||||
|
||||
if (newUrl !== null) {
|
||||
window.location.href = newUrl
|
||||
|
@ -407,7 +406,7 @@ export function urlincrement(count = 1){
|
|||
*/
|
||||
//#content
|
||||
export function urlroot (){
|
||||
let rootUrl = getUrlRoot(window.location)
|
||||
let rootUrl = UrlUtil.getUrlRoot(window.location)
|
||||
|
||||
if (rootUrl !== null) {
|
||||
window.location.href = rootUrl.href
|
||||
|
@ -418,13 +417,95 @@ export function urlroot (){
|
|||
*/
|
||||
//#content
|
||||
export function urlparent (count = 1){
|
||||
let parentUrl = getUrlParent(window.location, count)
|
||||
let parentUrl = UrlUtil.getUrlParent(window.location, count)
|
||||
|
||||
if (parentUrl !== null) {
|
||||
window.location.href = parentUrl.href
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a URL made by modifying the current URL
|
||||
*
|
||||
* @param mode -t text replace
|
||||
* -r regexp replace
|
||||
* -q replace the value of the given query
|
||||
* -Q delete the given query
|
||||
* -g graft a new path onto URL or parent path of it
|
||||
* @param replacement the replacement arguments:
|
||||
* -t <old> <new>
|
||||
* -r <regexp> <new> [flags]
|
||||
* -q <query> <new_val>
|
||||
* -Q <query>
|
||||
* -g <graftPoint> <newPathTail>
|
||||
* - graftPoint > 1 to count from left
|
||||
* - graftPoint < 0 to count from right
|
||||
*/
|
||||
//#content
|
||||
export function urlmodify(mode: "-t" | "-r" | "-q" | "-Q" | "-g", ...args: string[]) {
|
||||
|
||||
let oldUrl = new URL(window.location.href)
|
||||
let newUrl = undefined
|
||||
|
||||
switch(mode) {
|
||||
|
||||
case "-t":
|
||||
if (args.length !== 2) {
|
||||
throw new Error("Text replacement needs 2 arguments:"
|
||||
+ "<old> <new>")
|
||||
}
|
||||
|
||||
newUrl = oldUrl.href.replace(args[0], args[1])
|
||||
break
|
||||
|
||||
case "-r":
|
||||
if (args.length < 2 || args.length > 3) {
|
||||
throw new Error("RegExp replacement takes 2 or 3 arguments: "
|
||||
+ "<regexp> <new> [flags]")
|
||||
}
|
||||
|
||||
if (args[2] && args[2].search('/^[gi]+$/') === -1)
|
||||
{
|
||||
throw new Error("RegExp replacement flags can only include 'g', 'i'")
|
||||
}
|
||||
|
||||
let regexp = new RegExp(args[0], args[2])
|
||||
newUrl = oldUrl.href.replace(regexp, args[1])
|
||||
break
|
||||
|
||||
case "-q":
|
||||
if (args.length !== 2) {
|
||||
throw new Error("Query replacement needs 2 arguments:"
|
||||
+ "<query> <new_val>")
|
||||
}
|
||||
|
||||
newUrl = UrlUtil.replaceQueryValue(oldUrl, args[0],
|
||||
args[1])
|
||||
break
|
||||
case "-Q":
|
||||
if (args.length !== 1) {
|
||||
throw new Error("Query deletion needs 1 argument:"
|
||||
+ "<query>")
|
||||
}
|
||||
|
||||
newUrl = UrlUtil.deleteQuery(oldUrl, args[0])
|
||||
break
|
||||
|
||||
case "-g":
|
||||
if (args.length !== 2) {
|
||||
throw new Error("URL path grafting needs 2 arguments:"
|
||||
+ "<graft point> <new path tail>")
|
||||
}
|
||||
|
||||
newUrl = UrlUtil.graftUrlPath(oldUrl, args[1], Number(args[0]))
|
||||
break
|
||||
}
|
||||
|
||||
if (newUrl && newUrl !== oldUrl) {
|
||||
window.location.href = newUrl
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the url of links that have a matching rel.
|
||||
|
||||
Don't bind to this: it's an internal function.
|
||||
|
|
|
@ -127,7 +127,189 @@ function test_download_filename() {
|
|||
}
|
||||
}
|
||||
|
||||
function test_query_delete() {
|
||||
|
||||
let cases = [
|
||||
// no query
|
||||
[
|
||||
"http://example.com/",
|
||||
"query",
|
||||
"http://example.com/"
|
||||
],
|
||||
// single query=val, removed
|
||||
[
|
||||
"http://example.com/?query=val",
|
||||
"query",
|
||||
"http://example.com/"
|
||||
],
|
||||
// single query (no val), removed
|
||||
[
|
||||
"http://example.com/?query",
|
||||
"query",
|
||||
"http://example.com/"
|
||||
],
|
||||
// single query=val, not removed
|
||||
[
|
||||
"http://example.com/?query=val",
|
||||
"nomatch",
|
||||
"http://example.com/?query=val",
|
||||
],
|
||||
// single query (no val), not removed
|
||||
[
|
||||
"http://example.com/?query",
|
||||
"nomatch",
|
||||
"http://example.com/?query",
|
||||
],
|
||||
|
||||
// multiple queries, first removed
|
||||
[
|
||||
"http://example.com/?query=val&another=val2",
|
||||
"query",
|
||||
"http://example.com/?another=val2"
|
||||
],
|
||||
// multiple queries, second removed
|
||||
[
|
||||
"http://example.com/?query=val&another=val2",
|
||||
"another",
|
||||
"http://example.com/?query=val"
|
||||
],
|
||||
// multiple queries, repeated removed
|
||||
[
|
||||
"http://example.com/?query=val&another=val2&query=val3",
|
||||
"query",
|
||||
"http://example.com/?another=val2"
|
||||
],
|
||||
|
||||
]
|
||||
|
||||
for (let [url, q, exp_res] of cases) {
|
||||
|
||||
let modified = UrlUtil.deleteQuery(new URL(url), q)
|
||||
|
||||
test (`delete query ${q} of ${url} --> ${exp_res}`,
|
||||
() => expect(modified.href).toEqual(exp_res)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function test_query_replace() {
|
||||
|
||||
let cases = [
|
||||
// no query
|
||||
[
|
||||
"http://example.com/",
|
||||
"query", "val",
|
||||
"http://example.com/"
|
||||
],
|
||||
// single query
|
||||
[
|
||||
"http://example.com/?query=val",
|
||||
"query", "newval",
|
||||
"http://example.com/?query=newval"
|
||||
],
|
||||
// single query, no replacement value
|
||||
[
|
||||
"http://example.com/?query=val",
|
||||
"query", "",
|
||||
"http://example.com/?query"
|
||||
],
|
||||
// multiple, replace first
|
||||
[
|
||||
"http://example.com/?query1=val1&query2=val2",
|
||||
"query1", "newval1",
|
||||
"http://example.com/?query1=newval1&query2=val2"
|
||||
],
|
||||
// multiple, replace last
|
||||
[
|
||||
"http://example.com/?query1=val1&query2=val2",
|
||||
"query2", "newval2",
|
||||
"http://example.com/?query1=val1&query2=newval2"
|
||||
],
|
||||
|
||||
]
|
||||
|
||||
for (let [url, q, v, exp_res] of cases) {
|
||||
|
||||
let modified = UrlUtil.replaceQueryValue(new URL(url), q, v)
|
||||
|
||||
test (`change query ${q} of ${url} --> ${exp_res}`,
|
||||
() => expect(modified.href).toEqual(exp_res)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function test_url_graft_path() {
|
||||
|
||||
let cases = [
|
||||
// FROM LEFT
|
||||
[
|
||||
// complete replacement
|
||||
"http://example.com/foo/bar/quux",
|
||||
"0", "frob",
|
||||
"http://example.com/frob"
|
||||
],
|
||||
[
|
||||
// one level down
|
||||
"http://example.com/foo/bar/quux",
|
||||
"1", "frob",
|
||||
"http://example.com/foo/frob"
|
||||
],
|
||||
[
|
||||
// at last level
|
||||
"http://example.com/foo/bar/quux",
|
||||
"3", "frob",
|
||||
"http://example.com/foo/bar/quux/frob"
|
||||
],
|
||||
|
||||
// FROM RIGHT
|
||||
[
|
||||
// test of extend-only
|
||||
"http://example.com/test",
|
||||
"-1", "newchild",
|
||||
"http://example.com/test/newchild"
|
||||
],
|
||||
[
|
||||
// test of one level up graft (i.e. sibling)
|
||||
"http://example.com/test",
|
||||
"-2", "newsibling",
|
||||
"http://example.com/newsibling"
|
||||
],
|
||||
[
|
||||
// test of multi level up graft (i.e. cousin)
|
||||
"http://example.com/shop/by-id/42",
|
||||
"-3", "by-name/foobar",
|
||||
"http://example.com/shop/by-name/foobar"
|
||||
],
|
||||
|
||||
// ERRORS
|
||||
[
|
||||
// test of level too large and positive
|
||||
"http://example.com/foo",
|
||||
"2", "dummy",
|
||||
null
|
||||
],
|
||||
[
|
||||
// test of level too large and negative
|
||||
"http://example.com/foo",
|
||||
"-3", "dummy",
|
||||
null
|
||||
],
|
||||
]
|
||||
|
||||
for (let [url, level, tail, exp_res] of cases) {
|
||||
|
||||
let modified = UrlUtil.graftUrlPath(new URL(url), tail, Number(level))
|
||||
|
||||
test (`graft ${tail} onto ${url} at level ${level} --> ${exp_res}`,
|
||||
() => expect(modified ? modified.href : modified).toEqual(exp_res)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
test_increment()
|
||||
test_root()
|
||||
test_parent()
|
||||
test_download_filename()
|
||||
test_query_delete()
|
||||
test_query_replace()
|
||||
test_url_graft_path()
|
||||
|
|
135
src/url_util.ts
135
src/url_util.ts
|
@ -206,3 +206,138 @@ export function getDownloadFilenameForUrl(url: URL): string {
|
|||
// default is just "download"
|
||||
return url.hostname || "download"
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Array of the queries in a URL.
|
||||
*
|
||||
* These could be like "query" or "query=val"
|
||||
*/
|
||||
function getUrlQueries(url: URL): Array<string> {
|
||||
|
||||
let qys = []
|
||||
|
||||
if (url.search) {
|
||||
|
||||
// get each query separately, leave the "?" off
|
||||
qys = url.search.slice(1).split('&')
|
||||
}
|
||||
|
||||
return qys
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a URL with a new array of queries
|
||||
*/
|
||||
function setUrlQueries(url: URL, qys: Array<string>) {
|
||||
|
||||
url.search = ""
|
||||
|
||||
if (qys.length) {
|
||||
// rebuild string with the filtered list
|
||||
url.search = "?" + qys.join("&")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a query (and its value) in a URL
|
||||
*
|
||||
* If a query appears multiple times (which is a bit odd),
|
||||
* all instances are removed
|
||||
*
|
||||
* @param url the URL to act on
|
||||
* @param query the query to delete
|
||||
*
|
||||
* @return the modified URL
|
||||
*/
|
||||
export function deleteQuery(url: URL, matchQuery: string): URL {
|
||||
|
||||
let newUrl = new URL(url.href)
|
||||
|
||||
let qys = getUrlQueries(url)
|
||||
|
||||
let new_qys = qys.filter(q => {
|
||||
return q.split("=")[0] !== matchQuery
|
||||
})
|
||||
|
||||
setUrlQueries(newUrl, new_qys)
|
||||
|
||||
return newUrl
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the value of a query in a URL with a new one
|
||||
*
|
||||
* @param url the URL to act on
|
||||
* @param matchQuery the query key to replace the value for
|
||||
* @param newVal the new value to use
|
||||
*/
|
||||
export function replaceQueryValue(url: URL, matchQuery: string,
|
||||
newVal: string): URL {
|
||||
|
||||
let newUrl = new URL(url.href)
|
||||
|
||||
// get each query separately, leave the "?" off
|
||||
let qys = getUrlQueries(url)
|
||||
|
||||
let new_qys = qys.map(q => {
|
||||
|
||||
let [key, oldVal] = q.split('=')
|
||||
|
||||
// found a matching query key
|
||||
if (q.split("=")[0] === matchQuery) {
|
||||
|
||||
// return key=val or key as needed
|
||||
if (newVal) {
|
||||
return key + "=" + newVal
|
||||
} else {
|
||||
return key
|
||||
}
|
||||
}
|
||||
|
||||
// don't touch it
|
||||
return q
|
||||
})
|
||||
|
||||
setUrlQueries(newUrl, new_qys)
|
||||
|
||||
return newUrl
|
||||
}
|
||||
|
||||
/**
|
||||
* Graft a new path onto some parent of the current URL
|
||||
*
|
||||
* E.g. grafting "by-name/foobar" onto the 2nd parent path:
|
||||
* example.com/items/by-id/42 -> example.com/items/by-name/foobar
|
||||
*
|
||||
* @param url the URL to modify
|
||||
* @param newTail the new "grafted" URL path tail
|
||||
* @param level the graft point in terms of path levels
|
||||
* >= 0: start at / and count right
|
||||
* <0: start at the current path and count left
|
||||
*/
|
||||
export function graftUrlPath(url: URL, newTail: string, level: number) {
|
||||
|
||||
let newUrl = new URL(url.href)
|
||||
|
||||
// path parts, ignore first /
|
||||
let pathParts = url.pathname.split("/").splice(1)
|
||||
|
||||
// more levels than we can handle
|
||||
// (remember, if level <0, we start at -1)
|
||||
if ((level >= 0 && level > pathParts.length)
|
||||
|| (level < 0 && (-level - 1) > pathParts.length)) {
|
||||
return null
|
||||
}
|
||||
|
||||
let graftPoint = (level >= 0) ? level : (pathParts.length + level+ 1)
|
||||
|
||||
// lop off parts after the graft point
|
||||
pathParts.splice(graftPoint, pathParts.length - graftPoint)
|
||||
|
||||
// extend part array with new parts
|
||||
pathParts.push(...newTail.split("/"))
|
||||
|
||||
newUrl.pathname = pathParts.join("/")
|
||||
|
||||
return newUrl
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue