mirror of
https://github.com/vale981/tridactyl
synced 2025-03-06 01:51:40 -05:00
Merge branch 'master' of github.com:cmcaine/tridactyl into nativemessenger
Merge in version 1.9.4: I wanted the about:newtab code.
This commit is contained in:
commit
98734fb3a8
13 changed files with 190 additions and 35 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
AMOKEYS
|
||||
build
|
||||
node_modules
|
||||
src/excmds_background.ts
|
||||
|
|
|
@ -1,5 +1,27 @@
|
|||
# Tridactyl changelogs
|
||||
|
||||
## Release 1.9.4
|
||||
|
||||
- Add jumplist for inputs bound to `g;`
|
||||
- Editor's impartial note: this is pretty cool
|
||||
- Add `hint -W [exstr]` to execute exstr on hint's href
|
||||
- Update new tab page:
|
||||
- Add changelogs
|
||||
- Remove welcome to new users as we have `tutor` for that now
|
||||
- Fix newtab redirection on `set newtab [url]`
|
||||
- `set newtab about:blank` now works thanks to a Mozilla bug fix!
|
||||
- Warn users about native messenger update
|
||||
- Bug fixes
|
||||
- input-mode now correctly exits to normal mode on focus loss
|
||||
- Stop treating "std::map" or "Error: foo" as URIs: searching for them will now work.
|
||||
|
||||
## Release 1.9.3
|
||||
|
||||
- Fix unbind issues
|
||||
- Add more default binds from Vimperator
|
||||
- Change the `^` bind to `<c-6>` (matches vim)
|
||||
- :bmark now supports folders
|
||||
|
||||
## Release 1.9.2
|
||||
|
||||
- Fix #392 (bug with keyseq)
|
||||
|
|
|
@ -5,7 +5,24 @@
|
|||
cd src/static
|
||||
|
||||
newtab="../../generated/static/newtab.html"
|
||||
newtabtemp="../../generated/static/newtab.temp.html"
|
||||
|
||||
sed "/REPLACETHIS/,$ d" newtab.template.html > "$newtab"
|
||||
marked newtab.md >> "$newtab"
|
||||
sed "1,/REPLACETHIS/ d" newtab.template.html >> "$newtab"
|
||||
sed "/REPLACETHIS/,$ d" newtab.template.html > "$newtabtemp"
|
||||
marked newtab.md >> "$newtabtemp"
|
||||
sed "1,/REPLACETHIS/ d" newtab.template.html >> "$newtabtemp"
|
||||
|
||||
# Why think when you can pattern match?
|
||||
|
||||
sed "/REPLACE_ME_WITH_THE_CHANGE_LOG_USING_SED/,$ d" "$newtabtemp" > "$newtab"
|
||||
echo """
|
||||
<input type="checkbox" id="spoilerbutton" />
|
||||
<label for="spoilerbutton" onclick="">Changelogs</label>
|
||||
<div class="spoiler">
|
||||
""" >> "$newtab"
|
||||
marked ../../doc/changelog.md >> "$newtab"
|
||||
echo """
|
||||
</div>
|
||||
""" >> "$newtab"
|
||||
sed "1,/REPLACE_ME_WITH_THE_CHANGE_LOG_USING_SED/ d" "$newtabtemp" >> "$newtab"
|
||||
|
||||
rm "$newtabtemp"
|
||||
|
|
|
@ -19,6 +19,7 @@ publish_stable() {
|
|||
npm run clean
|
||||
npm run build
|
||||
sign_and_submit
|
||||
tar --exclude-from=.gitignore --exclude=.git/* -czf ../public_html/betas/tridactyl_source.tar.gz .
|
||||
}
|
||||
|
||||
case $1 in
|
||||
|
|
|
@ -79,6 +79,7 @@ const DEFAULTS = o({
|
|||
r: "reload",
|
||||
R: "reloadhard",
|
||||
gi: "focusinput -l",
|
||||
"g;": "changelistjump -1",
|
||||
gt: "tabnext_gt",
|
||||
gT: "tabprev",
|
||||
// "<c-n>": "tabnext_gt", // c-n is reserved for new window
|
||||
|
|
|
@ -49,15 +49,17 @@ import * as native from "./native_background"
|
|||
native,
|
||||
})
|
||||
|
||||
dom.setupFocusHandler()
|
||||
dom.hijackPageListenerFunctions()
|
||||
// Don't hijack on the newtab page.
|
||||
if (webext.inContentScript()) {
|
||||
dom.setupFocusHandler()
|
||||
dom.hijackPageListenerFunctions()
|
||||
} else {
|
||||
console.error("No export func")
|
||||
}
|
||||
|
||||
if (
|
||||
window.location.protocol === "moz-extension:" &&
|
||||
window.location.pathname === "/static/newtab.html"
|
||||
) {
|
||||
;(window as any).tri.config.getAsync("newtab").then(newtab => {
|
||||
if (newtab !== "")
|
||||
window.location.href = (window as any).tri.excmds.forceURI(newtab)
|
||||
})
|
||||
config.getAsync("newtab").then(newtab => newtab && excmds.open(newtab))
|
||||
}
|
||||
|
|
|
@ -41,14 +41,13 @@ function* ParserController() {
|
|||
if (
|
||||
state.mode != "ignore" &&
|
||||
state.mode != "hint" &&
|
||||
state.mode != "input" &&
|
||||
state.mode != "find"
|
||||
) {
|
||||
if (isTextEditable(keyevent.target)) {
|
||||
if (state.mode !== "insert") {
|
||||
state.mode = "insert"
|
||||
}
|
||||
} else if (state.mode === "insert") {
|
||||
} else if (["insert", "input"].includes(state.mode)) {
|
||||
state.mode = "normal"
|
||||
}
|
||||
}
|
||||
|
|
30
src/dom.ts
30
src/dom.ts
|
@ -1,6 +1,8 @@
|
|||
import { MsgSafeNode } from "./msgsafe"
|
||||
import * as config from "./config"
|
||||
import { flatten } from "./itertools"
|
||||
import state from "./state"
|
||||
import { activeTabId } from "./lib/webext"
|
||||
|
||||
// From saka-key lib/dom.js, under Apachev2
|
||||
|
||||
|
@ -432,8 +434,8 @@ export function focus(e: HTMLElement): void {
|
|||
//#content_helper
|
||||
let LAST_USED_INPUT: HTMLElement = null
|
||||
|
||||
export function getLastUsedInput () {
|
||||
return LAST_USED_INPUT
|
||||
export function getLastUsedInput() {
|
||||
return LAST_USED_INPUT
|
||||
}
|
||||
|
||||
/** WARNING: This function can potentially recieve malicious input! For the
|
||||
|
@ -447,17 +449,23 @@ export function getLastUsedInput () {
|
|||
function onPageFocus(elem: HTMLElement, args: any[]): void {
|
||||
if (isTextEditable(elem)) {
|
||||
LAST_USED_INPUT = elem
|
||||
config.getAsync("allowautofocus").then((allow) => {
|
||||
if (allow === "true")
|
||||
elem.focus(args)
|
||||
});
|
||||
config.getAsync("allowautofocus").then(allow => {
|
||||
if (allow === "true") elem.focus(args)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function setInput(el) {
|
||||
let tab = await activeTabId()
|
||||
// store maximum of 10 elements to stop this getting bonkers huge
|
||||
const arr = state.prevInputs.concat({ tab, inputId: el.id })
|
||||
state.prevInputs = arr.slice(Math.max(arr.length - 10, 0))
|
||||
}
|
||||
|
||||
/** Replaces the page's HTMLElement.prototype.focus with our own, onPageFocus */
|
||||
function hijackPageFocusFunction(): void {
|
||||
let exportedName = "onPageFocus";
|
||||
exportFunction(onPageFocus, window, {defineAs: exportedName})
|
||||
let exportedName = "onPageFocus"
|
||||
exportFunction(onPageFocus, window, { defineAs: exportedName })
|
||||
|
||||
let eval_str = `HTMLElement.prototype.focus = ((realFocus, ${exportedName}) => {
|
||||
return function (...args) {
|
||||
|
@ -465,14 +473,16 @@ function hijackPageFocusFunction(): void {
|
|||
}
|
||||
})(HTMLElement.prototype.focus, ${exportedName})`
|
||||
|
||||
window.eval(eval_str + `;delete ${exportedName}`)
|
||||
window.eval(eval_str + `;delete ${exportedName}`)
|
||||
}
|
||||
|
||||
export function setupFocusHandler(): void {
|
||||
// Handles when a user selects an input
|
||||
document.addEventListener("focusin", e => {
|
||||
if (isTextEditable(e.target as HTMLElement))
|
||||
if (isTextEditable(e.target as HTMLElement)) {
|
||||
LAST_USED_INPUT = e.target as HTMLElement
|
||||
setInput(e.target as HTMLInputElement)
|
||||
}
|
||||
})
|
||||
// Handles when the page tries to select an input
|
||||
hijackPageFocusFunction()
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
|
||||
// Shared
|
||||
import * as Messaging from "./messaging"
|
||||
import { l } from "./lib/webext"
|
||||
import { l, browserBg, activeTabId } from "./lib/webext"
|
||||
import state from "./state"
|
||||
import * as UrlUtil from "./url_util"
|
||||
import * as config from "./config"
|
||||
|
@ -114,7 +114,7 @@ import { flatten } from "./itertools"
|
|||
import "./number.mod"
|
||||
import { ModeName } from "./state"
|
||||
import * as keydown from "./keydown_background"
|
||||
import { activeTab, activeTabId, firefoxVersionAtLeast, openInNewTab } from "./lib/webext"
|
||||
import { activeTab, firefoxVersionAtLeast, openInNewTab } from "./lib/webext"
|
||||
import * as CommandLineBackground from "./commandline_background"
|
||||
|
||||
//#background_helper
|
||||
|
@ -211,15 +211,24 @@ function searchURL(provider: string, query: string) {
|
|||
return UrlUtil.interpolateSearchItem(new URL(searchurlprovider), query)
|
||||
}
|
||||
|
||||
/** If maybeURI doesn't have a schema, affix http:// */
|
||||
/** Take a string and find a way to interpret it as a URI or search query. */
|
||||
/** @hidden */
|
||||
export function forceURI(maybeURI: string): string {
|
||||
// Need undefined to be able to open about:newtab
|
||||
if (maybeURI == "") return undefined
|
||||
try {
|
||||
return new URL(maybeURI).href
|
||||
} catch (e) {
|
||||
if (e.name !== "TypeError") throw e
|
||||
|
||||
// If the uri looks like it might contain a schema and a domain, try url()
|
||||
// test for a non-whitespace, non-colon character after the colon to avoid
|
||||
// false positives like "error: can't reticulate spline" and "std::map".
|
||||
//
|
||||
// These heuristics mean that very unusual URIs will be coerced to
|
||||
// something else by this function.
|
||||
if (/^[a-zA-Z0-9+.-]+:[^\s:]/.test(maybeURI)) {
|
||||
try {
|
||||
return new URL(maybeURI).href
|
||||
} catch (e) {
|
||||
if (e.name !== "TypeError") throw e
|
||||
}
|
||||
}
|
||||
|
||||
// Else if search keyword:
|
||||
|
@ -449,10 +458,16 @@ export async function reloadhard(n = 1) {
|
|||
"searchengine": "google" or any of [[SEARCH_URLS]]
|
||||
*/
|
||||
//#content
|
||||
export function open(...urlarr: string[]) {
|
||||
export async function open(...urlarr: string[]) {
|
||||
let url = urlarr.join(" ")
|
||||
if (url === "") url = config.get("newtab") || browser.extension.getURL("static/newtab.html")
|
||||
window.location.href = forceURI(url)
|
||||
|
||||
// Setting window.location to about:blank results in a page we can't access, tabs.update works.
|
||||
// tabs.update goes to the new tab page if url === "".
|
||||
if (["", "about:blank"].includes(url)) {
|
||||
browserBg.tabs.update(await activeTabId(), { url })
|
||||
} else {
|
||||
window.location.href = forceURI(url)
|
||||
}
|
||||
}
|
||||
|
||||
/** @hidden */
|
||||
|
@ -911,6 +926,41 @@ export function focusinput(nth: number | string) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus the tab which contains the last focussed input element. If you're lucky, it will focus the right input, too.
|
||||
*
|
||||
* Currently just goes to the last focussed input; being able to jump forwards and backwards is planned.
|
||||
*/
|
||||
//#background
|
||||
export async function changelistjump(n?: number) {
|
||||
let tail = state.prevInputs[state.prevInputs.length - 1]
|
||||
let jumppos = tail.jumppos ? tail.jumppos : state.prevInputs.length - 1
|
||||
const input = state.prevInputs[jumppos]
|
||||
await browser.tabs.update(input.tab, { active: true })
|
||||
const id = input.inputId
|
||||
// Not all elements have an ID, so this will do for now.
|
||||
if (id) focusbyid(input.inputId)
|
||||
else focusinput("-l")
|
||||
|
||||
// Really want to bin the input we just focussed ^ and edit the real last input to tell us where to jump to next.
|
||||
// It doesn't work in practice as the focus events get added after we try to delete them.
|
||||
// Even editing focusbyid/focusinput doesn't work to try to delete their own history doesn't work.
|
||||
// I'm bored of working on it for now, though.
|
||||
// Probable solution: add an event listener to state.prevInputs changing, delete the focussed element, then delete event listener.
|
||||
//
|
||||
// let arr = state.prevInputs
|
||||
// arr.splice(-2,2)
|
||||
|
||||
// tail.jumppos = jumppos - 1
|
||||
// arr = arr.concat(tail)
|
||||
// state.prevInputs = arr
|
||||
}
|
||||
|
||||
//#content
|
||||
export function focusbyid(id: string) {
|
||||
document.getElementById(id).focus()
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ TABS
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Tridactyl",
|
||||
"version": "1.9.2",
|
||||
"version": "1.9.4",
|
||||
"icons": {
|
||||
"64": "static/logo/Tridactyl_64px.png",
|
||||
"100": "static/logo/Tridactyl_100px.png",
|
||||
|
|
|
@ -28,6 +28,13 @@ export type ModeName =
|
|||
class State {
|
||||
mode: ModeName = "normal"
|
||||
cmdHistory: string[] = []
|
||||
prevInputs: { inputId: string; tab: number; jumppos?: number }[] = [
|
||||
{
|
||||
inputId: undefined,
|
||||
tab: undefined,
|
||||
jumppos: undefined,
|
||||
},
|
||||
]
|
||||
last_ex_str: string = ""
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,47 @@ body {
|
|||
margin: auto;
|
||||
}
|
||||
|
||||
input[id^="spoiler"]{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Borrowed from https://codepen.io/oloman/pen/odnqy */
|
||||
input[id^="spoiler"] + label {
|
||||
display: block;
|
||||
width: 8em;
|
||||
margin: 0 auto;
|
||||
padding: 0.25em, 0.25em;
|
||||
background: #1f9947;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 12pt;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all .6s;
|
||||
}
|
||||
input[id^="spoiler"]:checked + label {
|
||||
color: #333;
|
||||
background: #ccc;
|
||||
}
|
||||
input[id^="spoiler"] ~ .spoiler {
|
||||
width: 90%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
margin: 10px auto 0;
|
||||
padding: 10px;
|
||||
background: #eee;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 2px;
|
||||
transition: all .6s;
|
||||
}
|
||||
input[id^="spoiler"]:checked + label + .spoiler{
|
||||
height: auto;
|
||||
opacity: 1;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
|
||||
h1 {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Tridactyl REPLACE_ME_WITH_THE_VERSION_USING_SED
|
||||
|
||||
Tridactyl has to override your new tab page due to WebExtension limitations. You can learn how to change it at the bottom of the page, otherwise please read on for some tips and tricks. (If you've just installed Tridactyl for the first time and are seeing this page, hello! Welcome! You'll probably be seeing this page a lot until you figure out how to disable it or uninstall the addon).
|
||||
Tridactyl has to override your new tab page due to WebExtension limitations. You can learn how to change it at the bottom of the page, otherwise please read on for some tips and tricks.
|
||||
|
||||
- You can view the main help page by typing [`:help`][help], and access the tutorial with [`:tutor`][tutor].
|
||||
|
||||
|
@ -12,6 +12,11 @@ Tridactyl has to override your new tab page due to WebExtension limitations. You
|
|||
|
||||
- If you're enjoying Tridactyl (or not), please leave a review on [addons.mozilla.org][amo].
|
||||
|
||||
- **NB:** Tridactyl will soon support a native messenger. When this version is released, Firefox **will not update to it** unless you click the menu in the top right and allow it to update. A small yellow exclamation mark will appear on the menu's icon to notify you of this fact; please keep an eye out for it over the next week or so.
|
||||
|
||||
|
||||
REPLACE_ME_WITH_THE_CHANGE_LOG_USING_SED
|
||||
|
||||
## Highlighted features:
|
||||
|
||||
- `f`/`F` — enter the "hint mode" to select a link to follow. `F` to open it in a background tab.
|
||||
|
@ -47,8 +52,7 @@ Tridactyl overrides your newtab page because it cannot insert its content script
|
|||
### How can I get rid of it?
|
||||
|
||||
- `:set newtab [URL]`
|
||||
<!-- - If you just want a blank page, you can use `set newtab data:text/html, <html style="background:white"></html>`. You can replace "white" with any CSS colour of your choosing. -->
|
||||
- `d`, Alt-F4, Ctrl-W and other such jokes.
|
||||
- e.g, `:set newtab about:blank`
|
||||
|
||||
## FAQ
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue