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 glacambre-fix_#325
This commit is contained in:
commit
b7a833fcf5
6 changed files with 139 additions and 91 deletions
|
@ -159,6 +159,8 @@ const DEFAULTS = o({
|
||||||
"hintchars": "hjklasdfgyuiopqwertnmzxcvb",
|
"hintchars": "hjklasdfgyuiopqwertnmzxcvb",
|
||||||
"hintfiltermode": "simple", // "simple", "vimperator", "vimperator-reflow"
|
"hintfiltermode": "simple", // "simple", "vimperator", "vimperator-reflow"
|
||||||
|
|
||||||
|
tabopenpos: 'next',
|
||||||
|
relatedopenpos: 'related',
|
||||||
"ttsvoice": "default", // chosen from the listvoices list, or "default"
|
"ttsvoice": "default", // chosen from the listvoices list, or "default"
|
||||||
"ttsvolume": 1, // 0 to 1
|
"ttsvolume": 1, // 0 to 1
|
||||||
"ttsrate": 1, // 0.1 to 10
|
"ttsrate": 1, // 0.1 to 10
|
||||||
|
|
|
@ -68,44 +68,38 @@
|
||||||
|
|
||||||
// {{{ setup
|
// {{{ setup
|
||||||
|
|
||||||
|
// Shared
|
||||||
import * as Messaging from "./messaging"
|
import * as Messaging from "./messaging"
|
||||||
import {l} from './lib/webext'
|
import {l} from './lib/webext'
|
||||||
import state from "./state"
|
import state from "./state"
|
||||||
|
|
||||||
//#content_omit_line
|
|
||||||
import "./number.clamp"
|
|
||||||
//#content_helper
|
|
||||||
import * as SELF from "./excmds_content"
|
|
||||||
//#content_helper
|
|
||||||
Messaging.addListener('excmd_content', Messaging.attributeCaller(SELF))
|
|
||||||
/** Message excmds_content.ts in the active tab of the currentWindow */
|
|
||||||
//#background_helper
|
|
||||||
import {messageActiveTab} from './messaging'
|
|
||||||
|
|
||||||
//#background_helper
|
|
||||||
import "./number.mod"
|
|
||||||
//#background_helper
|
|
||||||
import {ModeName} from './state'
|
|
||||||
//#background_helper
|
|
||||||
import * as keydown from "./keydown_background"
|
|
||||||
//#background_helper
|
|
||||||
import {activeTab, activeTabId, firefoxVersionAtLeast} from './lib/webext'
|
|
||||||
import * as UrlUtil from "./url_util"
|
import * as UrlUtil from "./url_util"
|
||||||
|
|
||||||
//#background_helper
|
|
||||||
import * as CommandLineBackground from './commandline_background'
|
|
||||||
//#content_helper
|
|
||||||
import * as DOM from './dom'
|
|
||||||
|
|
||||||
import * as config from './config'
|
import * as config from './config'
|
||||||
|
import * as aliases from './aliases'
|
||||||
import * as Logging from "./logging"
|
import * as Logging from "./logging"
|
||||||
const logger = new Logging.Logger('excmds')
|
const logger = new Logging.Logger('excmds')
|
||||||
|
|
||||||
import * as aliases from './aliases'
|
//#content_helper
|
||||||
|
// {
|
||||||
|
import "./number.clamp"
|
||||||
|
import * as SELF from "./excmds_content"
|
||||||
|
Messaging.addListener('excmd_content', Messaging.attributeCaller(SELF))
|
||||||
|
import * as DOM from './dom'
|
||||||
|
// }
|
||||||
|
|
||||||
|
//#background_helper
|
||||||
|
// {
|
||||||
|
/** Message excmds_content.ts in the active tab of the currentWindow */
|
||||||
|
import {messageActiveTab} from './messaging'
|
||||||
|
|
||||||
|
import "./number.mod"
|
||||||
|
import {ModeName} from './state'
|
||||||
|
import * as keydown from "./keydown_background"
|
||||||
|
import {activeTab, activeTabId, firefoxVersionAtLeast, openInNewTab} from './lib/webext'
|
||||||
|
import * as CommandLineBackground from './commandline_background'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
//#background_helper
|
|
||||||
export const cmd_params = new Map<string, Map<string, string>>()
|
export const cmd_params = new Map<string, Map<string, string>>()
|
||||||
|
// }
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
function hasScheme(uri: string) {
|
function hasScheme(uri: string) {
|
||||||
|
@ -819,18 +813,26 @@ export async function tablast() {
|
||||||
|
|
||||||
Unlike Firefox's Ctrl-t shortcut, this opens tabs immediately after the
|
Unlike Firefox's Ctrl-t shortcut, this opens tabs immediately after the
|
||||||
currently active tab rather than at the end of the tab list because that is
|
currently active tab rather than at the end of the tab list because that is
|
||||||
the author's preference. Open an issue if you don't like it :)
|
the author's preference.
|
||||||
|
|
||||||
|
If you would rather the Firefox behaviour `set tabopenpos last`. This
|
||||||
|
preference also affects the clipboard, quickmarks, home, help, etc.
|
||||||
|
|
||||||
|
If you would rather the URL be opened as if you'd middle clicked it, `set
|
||||||
|
tabopenpos related`.
|
||||||
|
|
||||||
|
Hinting is controlled by `relatedopenlast`
|
||||||
|
|
||||||
*/
|
*/
|
||||||
//#background
|
//#background
|
||||||
export async function tabopen(...addressarr: string[]) {
|
export async function tabopen(...addressarr: string[]) {
|
||||||
let uri
|
let url: string
|
||||||
let address = addressarr.join(' ')
|
let address = addressarr.join(' ')
|
||||||
if (address != "") uri = forceURI(address)
|
|
||||||
else uri = forceURI(config.get("newtab"))
|
if (address != "") url = forceURI(address)
|
||||||
browser.tabs.create({
|
else url = forceURI(config.get("newtab"))
|
||||||
url: uri,
|
|
||||||
index: (await activeTabId()) + 1
|
openInNewTab(url)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve a tab index to the tab id of the corresponding tab in this window.
|
/** Resolve a tab index to the tab id of the corresponding tab in this window.
|
||||||
|
@ -1623,6 +1625,8 @@ import * as hinting from './hinting_background'
|
||||||
- -# yank an element's anchor URL to clipboard
|
- -# yank an element's anchor URL to clipboard
|
||||||
- -c [selector] hint links that match the css selector
|
- -c [selector] hint links that match the css selector
|
||||||
- `bind ;c hint -c [class*="expand"],[class="togg"]` works particularly well on reddit and HN
|
- `bind ;c hint -c [class*="expand"],[class="togg"]` works particularly well on reddit and HN
|
||||||
|
- -w open in new window
|
||||||
|
-wp open in new private window
|
||||||
|
|
||||||
Excepting the custom selector mode and background hint mode, each of these
|
Excepting the custom selector mode and background hint mode, each of these
|
||||||
hint modes is available by default as `;<option character>`, so e.g. `;y`
|
hint modes is available by default as `;<option character>`, so e.g. `;y`
|
||||||
|
@ -1633,6 +1637,7 @@ import * as hinting from './hinting_background'
|
||||||
Related settings:
|
Related settings:
|
||||||
"hintchars": "hjklasdfgyuiopqwertnmzxcvb"
|
"hintchars": "hjklasdfgyuiopqwertnmzxcvb"
|
||||||
"hintfiltermode": "simple" | "vimperator" | "vimperator-reflow"
|
"hintfiltermode": "simple" | "vimperator" | "vimperator-reflow"
|
||||||
|
"relatedopenpos": "related" | "next" | "last"
|
||||||
*/
|
*/
|
||||||
//#background
|
//#background
|
||||||
export function hint(option?: string, selectors="") {
|
export function hint(option?: string, selectors="") {
|
||||||
|
@ -1650,6 +1655,8 @@ export function hint(option?: string, selectors="") {
|
||||||
else if (option === "-#") hinting.hintPageAnchorYank()
|
else if (option === "-#") hinting.hintPageAnchorYank()
|
||||||
else if (option === "-c") hinting.hintPageSimple(selectors)
|
else if (option === "-c") hinting.hintPageSimple(selectors)
|
||||||
else if (option === "-r") hinting.hintRead()
|
else if (option === "-r") hinting.hintRead()
|
||||||
|
else if (option === "-w") hinting.hintPageWindow()
|
||||||
|
else if (option === "-wp") hinting.hintPageWindowPrivate()
|
||||||
else hinting.hintPageSimple()
|
else hinting.hintPageSimple()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -506,7 +506,7 @@ function simulateClick(target: HTMLElement) {
|
||||||
if ((target as HTMLAnchorElement).target === '_blank' ||
|
if ((target as HTMLAnchorElement).target === '_blank' ||
|
||||||
(target as HTMLAnchorElement).target === '_new'
|
(target as HTMLAnchorElement).target === '_new'
|
||||||
) {
|
) {
|
||||||
openInNewTab((target as HTMLAnchorElement).href)
|
openInNewTab((target as HTMLAnchorElement).href, {related: true})
|
||||||
} else {
|
} else {
|
||||||
DOM.mouseEvent(target, "click")
|
DOM.mouseEvent(target, "click")
|
||||||
// Sometimes clicking the element doesn't focus it sufficiently.
|
// Sometimes clicking the element doesn't focus it sufficiently.
|
||||||
|
@ -519,7 +519,7 @@ function hintPageOpenInBackground() {
|
||||||
hint.target.focus()
|
hint.target.focus()
|
||||||
if (hint.target.href) {
|
if (hint.target.href) {
|
||||||
// Try to open with the webext API. If that fails, simulate a click on this page anyway.
|
// Try to open with the webext API. If that fails, simulate a click on this page anyway.
|
||||||
openInNewTab(hint.target.href, false).catch(()=>simulateClick(hint.target))
|
openInNewTab(hint.target.href, {active: false, related: true}).catch(()=>simulateClick(hint.target))
|
||||||
} else {
|
} else {
|
||||||
// This is to mirror vimperator behaviour.
|
// This is to mirror vimperator behaviour.
|
||||||
simulateClick(hint.target)
|
simulateClick(hint.target)
|
||||||
|
@ -527,6 +527,29 @@ function hintPageOpenInBackground() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import {openInNewWindow} from './lib/webext'
|
||||||
|
|
||||||
|
function hintPageWindow() {
|
||||||
|
hintPage(hintables(), hint=>{
|
||||||
|
hint.target.focus()
|
||||||
|
if (hint.target.href) {
|
||||||
|
openInNewWindow({url: hint.target.href})
|
||||||
|
} else {
|
||||||
|
// This is to mirror vimperator behaviour.
|
||||||
|
simulateClick(hint.target)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function hintPageWindowPrivate() {
|
||||||
|
hintPage(hintables(), hint=>{
|
||||||
|
hint.target.focus()
|
||||||
|
if (hint.target.href) {
|
||||||
|
openInNewWindow({url: hint.target.href, incognito: true})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function hintPageSimple(selectors=HINTTAGS_selectors) {
|
function hintPageSimple(selectors=HINTTAGS_selectors) {
|
||||||
hintPage(hintables(selectors), hint=>{
|
hintPage(hintables(selectors), hint=>{
|
||||||
simulateClick(hint.target)
|
simulateClick(hint.target)
|
||||||
|
@ -569,7 +592,7 @@ function hintImage(inBackground) {
|
||||||
let img_src = hint.target.getAttribute("src")
|
let img_src = hint.target.getAttribute("src")
|
||||||
|
|
||||||
if (inBackground) {
|
if (inBackground) {
|
||||||
openInNewTab(new URL(img_src, window.location.href).href, false)
|
openInNewTab(new URL(img_src, window.location.href).href, {active: false, related: true})
|
||||||
} else {
|
} else {
|
||||||
window.location.href = img_src
|
window.location.href = img_src
|
||||||
}
|
}
|
||||||
|
@ -645,6 +668,8 @@ addListener('hinting_content', attributeCaller({
|
||||||
hintPageTextYank,
|
hintPageTextYank,
|
||||||
hintPageAnchorYank,
|
hintPageAnchorYank,
|
||||||
hintPageOpenInBackground,
|
hintPageOpenInBackground,
|
||||||
|
hintPageWindow,
|
||||||
|
hintPageWindowPrivate,
|
||||||
hintImage,
|
hintImage,
|
||||||
hintFocus,
|
hintFocus,
|
||||||
hintRead,
|
hintRead,
|
||||||
|
|
|
@ -32,6 +32,14 @@ export async function hintPageOpenInBackground() {
|
||||||
return await messageActiveTab('hinting_content', 'hintPageOpenInBackground')
|
return await messageActiveTab('hinting_content', 'hintPageOpenInBackground')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function hintPageWindow() {
|
||||||
|
return await messageActiveTab('hinting_content', 'hintPageWindow')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function hintPageWindowPrivate() {
|
||||||
|
return await messageActiveTab('hinting_content', 'hintPageWindowPrivate')
|
||||||
|
}
|
||||||
|
|
||||||
export async function hintImage(inBackground) {
|
export async function hintImage(inBackground) {
|
||||||
return await messageActiveTab('hinting_content', 'hintImage', [inBackground])
|
return await messageActiveTab('hinting_content', 'hintImage', [inBackground])
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,25 @@
|
||||||
import * as convert from '../convert'
|
import * as convert from '../convert'
|
||||||
import browserProxy from './browser_proxy'
|
import browserProxy from './browser_proxy'
|
||||||
|
import * as config from '../config'
|
||||||
|
|
||||||
export function inContentScript() {
|
export function inContentScript() {
|
||||||
return ! ('tabs' in browser)
|
return getContext() == 'content'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** WebExt code can be run from three contexts:
|
||||||
|
|
||||||
|
Content script
|
||||||
|
Extension page
|
||||||
|
Background page
|
||||||
|
*/
|
||||||
|
export function getContext() {
|
||||||
|
if (! ('tabs' in browser)) {
|
||||||
|
return 'content'
|
||||||
|
} else if (browser.runtime.getURL('_generated_background_page.html') == window.location.href) {
|
||||||
|
return 'background'
|
||||||
|
} else {
|
||||||
|
return 'extension'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let browserBg
|
export let browserBg
|
||||||
|
@ -53,17 +70,53 @@ export async function firefoxVersionAtLeast(desiredmajor: number) {
|
||||||
return actualmajor >= desiredmajor
|
return actualmajor >= desiredmajor
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Open a new tab with a URL as if that URL had been middle clicked on the current tab
|
/** Simpler tabs.create option.
|
||||||
|
|
||||||
|
If related = true && relatedopenpos = 'related' then open a new tab with
|
||||||
|
some URL as if that URL had been middle clicked on the current tab. If
|
||||||
|
relatedopenpos = 'next', open it as the next tab. If 'last', open it last
|
||||||
|
and don't tell Firefox who opened it.
|
||||||
|
|
||||||
|
Similarly for tabopenpos, but only tell FF that the newtab is related to
|
||||||
|
the activeTab if tabopenpos == 'related'.
|
||||||
|
|
||||||
i.e. place that tab just after the current tab and set openerTabId
|
i.e. place that tab just after the current tab and set openerTabId
|
||||||
*/
|
*/
|
||||||
export async function openInNewTab(url: string, active = true) {
|
export async function openInNewTab(url: string, kwargs: {active?, related?} = {active: true, related: false}) {
|
||||||
const thisTab = await activeTab()
|
const thisTab = await activeTab()
|
||||||
const options: any = {
|
const options: any = {
|
||||||
active,
|
active: kwargs.active,
|
||||||
url,
|
url,
|
||||||
index: thisTab.index + 1,
|
|
||||||
}
|
}
|
||||||
if (await l(firefoxVersionAtLeast(57))) options.openerTabId = thisTab.id
|
|
||||||
|
// Be nice to behrmann, #342
|
||||||
|
let pos
|
||||||
|
if (kwargs.related) pos = config.get('relatedopenpos')
|
||||||
|
else pos = config.get('tabopenpos')
|
||||||
|
switch (pos) {
|
||||||
|
case 'next':
|
||||||
|
options.index = thisTab.index + 1
|
||||||
|
if (kwargs.related && await l(firefoxVersionAtLeast(57)))
|
||||||
|
options.openerTabId = thisTab.id
|
||||||
|
break
|
||||||
|
case 'last':
|
||||||
|
// Infinity can't be serialised, apparently.
|
||||||
|
options.index = 99999
|
||||||
|
break
|
||||||
|
case 'related':
|
||||||
|
if (await l(firefoxVersionAtLeast(57))) {
|
||||||
|
options.openerTabId = thisTab.id
|
||||||
|
} else {
|
||||||
|
options.index = thisTab.index + 1
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
return browserBg.tabs.create(options)
|
return browserBg.tabs.create(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lazily copied from excmds.ts' winopen - forceURI really ought to be moved to lib/webext
|
||||||
|
// Should consider changing interface of this to match openInNewTab or vice versa
|
||||||
|
export async function openInNewWindow(createData = {}) {
|
||||||
|
browserBg.windows.create(createData)
|
||||||
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
# Inspired by QuantumVim: https://github.com/shinglyu/QuantumVim
|
|
||||||
|
|
||||||
BACKGROUND_COLOUR = "yellow"
|
|
||||||
|
|
||||||
highlight_links = () ->
|
|
||||||
links = document.querySelectorAll('a') # Just handles links, not buttons/inputs etc.
|
|
||||||
code = 0
|
|
||||||
for link in links
|
|
||||||
link_highlight(link, code)
|
|
||||||
code +=1
|
|
||||||
|
|
||||||
console.log(LINK_CODES)
|
|
||||||
return code
|
|
||||||
|
|
||||||
LINK_CODES = {}
|
|
||||||
|
|
||||||
link_highlight = (elem, code) ->
|
|
||||||
elem._background = elem.style.backgroundColor
|
|
||||||
elem._position = elem.style.position
|
|
||||||
# Why are these being saved?
|
|
||||||
elem.style.backgroundColor = BACKGROUND_COLOUR
|
|
||||||
elem.style.position="relative"
|
|
||||||
codehint = generate_codehint(code)
|
|
||||||
elem.appendChild(codehint)
|
|
||||||
LINK_CODES[String(code)] = {
|
|
||||||
element: elem
|
|
||||||
codehint
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_codehint = (code) ->
|
|
||||||
codehint = document.createElement('span')
|
|
||||||
codehint.textContent = "" + code
|
|
||||||
codehint.style.border = "solid 1 px black"
|
|
||||||
codehint.style.backgroundColor="white"
|
|
||||||
codehint.style.font="12px/14px bold sans-serif"
|
|
||||||
codehint.style.color="darkred"
|
|
||||||
codehint.style.position="absolute"
|
|
||||||
codehint.style.top="0"
|
|
||||||
codehint.style.left="0"
|
|
||||||
codehint.style.padding="0.1em"
|
|
||||||
codehint
|
|
||||||
|
|
||||||
linkMessageHandler = (message) ->
|
|
||||||
switch(message.command)
|
|
||||||
when "hint" then highlight_links()
|
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener(linkMessageHandler)
|
|
Loading…
Add table
Reference in a new issue