From 9bb8807c192df90cee88c37948eb8d12ac931fec Mon Sep 17 00:00:00 2001 From: James Magahern Date: Thu, 4 Mar 2021 16:07:30 -0800 Subject: [PATCH] Tagger: hold space now. hjkl to scroll --- App/AppDelegate.swift | 7 ++ .../BrowserViewController+Keyboard.swift | 4 + App/KeyboardShortcuts.swift | 3 + App/Resources/Tagger.js | 75 +++++++++++++++---- 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/App/AppDelegate.swift b/App/AppDelegate.swift index 7474b7b..4b7476c 100644 --- a/App/AppDelegate.swift +++ b/App/AppDelegate.swift @@ -43,6 +43,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { action: #selector(ShortcutResponder.focusURLBar) ), + // Focus Web View + UIKeyCommand( + modifiers: .command, input: "b", + title: "Focus Web View", + action: #selector(ShortcutResponder.focusWebView) + ), + // Go Back UIKeyCommand( modifiers: .command, input: "[", diff --git a/App/Browser View/BrowserViewController+Keyboard.swift b/App/Browser View/BrowserViewController+Keyboard.swift index 31b0dc8..11613c1 100644 --- a/App/Browser View/BrowserViewController+Keyboard.swift +++ b/App/Browser View/BrowserViewController+Keyboard.swift @@ -87,6 +87,10 @@ extension BrowserViewController: ShortcutResponder toolbarController.urlBar.textField.becomeFirstResponder() } + func focusWebView(_ sender: Any?) { + webView.becomeFirstResponder() + } + func goBack(_ sender: Any?) { tab.webView.goBack() } diff --git a/App/KeyboardShortcuts.swift b/App/KeyboardShortcuts.swift index 8786bfc..a3c1eda 100644 --- a/App/KeyboardShortcuts.swift +++ b/App/KeyboardShortcuts.swift @@ -12,6 +12,9 @@ protocol ShortcutResponder: AnyObject { @objc optional func focusURLBar(_ sender: Any?) + @objc + optional func focusWebView(_ sender: Any?) + @objc optional func goBack(_ sender: Any?) diff --git a/App/Resources/Tagger.js b/App/Resources/Tagger.js index 66ea511..39101fb 100644 --- a/App/Resources/Tagger.js +++ b/App/Resources/Tagger.js @@ -5,7 +5,7 @@ class ElementTagger { this.tagList = {}; const baseMnemonics = [ - 'a', 's', 'd', /* 'f', */ 'g', + 'a', 's', 'd', 'f', 'g', 'q', 'w', 'e', 'r', 't', 'z', 'x', 'c', 'v', 'b', 'y', 'u', 'i', 'o', 'p', @@ -14,8 +14,20 @@ class ElementTagger { ]; let additionalMnemonics = []; - baseMnemonics.forEach( (letter) => { - additionalMnemonics.push("" + letter.toUpperCase() + letter); + + // Upper + lower + baseMnemonics.forEach( (upperLetter) => { + upperLetter = upperLetter.toUpperCase(); + + // Upper + lower + baseMnemonics.forEach( (lowerLetter) => { + additionalMnemonics.push("" + upperLetter + lowerLetter); + }); + + // Upper + upper + baseMnemonics.forEach( (letter) => { + additionalMnemonics.push("" + upperLetter + letter.toUpperCase()); + }); }); let mnemonics = baseMnemonics.concat(additionalMnemonics); @@ -141,7 +153,6 @@ class ElementTagger { (function() { let tagger = new ElementTagger(); - var counter = 0; var tagAccum = []; document.addEventListener('keypress', (event) => { if (document.activeElement !== document.body) { @@ -153,16 +164,8 @@ class ElementTagger { return; } - if (keyName == 'f') { - if (++counter == 2) { - counter = 0; - if (tagger.isTagged) { - tagger.untagDocument(); - } else { - tagger.tagDocument(); - } - } - } else { + // Tagger + if (tagger.isTagged) { // Uppercase if (tagAccum.length > 0 || keyName.toUpperCase() == keyName) { tagAccum.push(keyName); @@ -176,6 +179,50 @@ class ElementTagger { tagger.clickLinkWithTag(keyName); tagger.untagDocument(); } + } else { + // Otherwise, interpret as a single character command + + let lowerKey = keyName.toLowerCase(); + let scrollAmount = event.shiftKey ? window.visualViewport.height : 30; + + var scrollOptions = { behavior: 'smooth' }; // currently doesn't work with WebKit + if (lowerKey == 'j') { + scrollOptions.top = scrollAmount; + } else if (lowerKey == 'k') { + scrollOptions.top = -scrollAmount; + } else if (lowerKey == 'h') { + scrollOptions.left = -scrollAmount; + } else if (lowerKey == 'l') { + scrollOptions.left = scrollAmount; + } + + window.scrollBy(scrollOptions); + } + }); + + document.addEventListener('keydown', (event) => { + if (document.activeElement !== document.body) { + return; + } + + if (event.key == " ") { + if (!tagger.isTagged) { + tagger.tagDocument(); + } + event.preventDefault(); + } + }); + + document.addEventListener('keyup', (event) => { + if (document.activeElement !== document.body) { + return; + } + + if (event.key == " " && tagger.isTagged) { + tagger.untagDocument(); + event.preventDefault(); } }); })(); + +