Moved URL bar input and mono mode toggle to CLI
Finally fixes integration tests
This commit is contained in:
parent
b605965e77
commit
ae44a18cfc
|
@ -34,7 +34,8 @@ install:
|
|||
- npm run build
|
||||
script:
|
||||
- cd $REPO_ROOT/webext && npm test
|
||||
- cd $REPO_ROOT/interfacer && ./contrib/run_tests.sh
|
||||
- cd $REPO_ROOT/interfacer && go test src/browsh/*.go -v
|
||||
- cd $REPO_ROOT/interfacer && go test test/*.go -v
|
||||
after_failure:
|
||||
- cat $REPO_ROOT/interfacer/test/debug.log
|
||||
after_success:
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
go test test/*.go -v
|
42
interfacer/src/browsh/input_box.go
Normal file
42
interfacer/src/browsh/input_box.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package browsh
|
||||
|
||||
import (
|
||||
"github.com/gdamore/tcell"
|
||||
)
|
||||
|
||||
var (
|
||||
activeInputBox *inputBox
|
||||
)
|
||||
|
||||
// A box into which you can enter text. Generally will be forwarded to a standard
|
||||
// HTML input box in the real browser.
|
||||
type inputBox struct {
|
||||
ID int `json:"id"`
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
isActive bool
|
||||
text string
|
||||
}
|
||||
|
||||
func handleInputBoxInput(ev *tcell.EventKey) {
|
||||
switch ev.Key() {
|
||||
case tcell.KeyLeft:
|
||||
case tcell.KeyRight:
|
||||
case tcell.KeyBackspace, tcell.KeyBackspace2:
|
||||
length := len(activeInputBox.text)
|
||||
if (length >= 1) {
|
||||
activeInputBox.text = activeInputBox.text[:length - 1]
|
||||
}
|
||||
case tcell.KeyEnter:
|
||||
sendMessageToWebExtension("/url_bar," + activeInputBox.text)
|
||||
urlBarFocusToggle()
|
||||
}
|
||||
character := string(ev.Rune())
|
||||
if ev.Key() == tcell.KeyRune {
|
||||
activeInputBox.text += character
|
||||
}
|
||||
renderURLBar()
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@ var (
|
|||
yScroll = 0
|
||||
screen tcell.Screen
|
||||
uiHeight = 2
|
||||
// IsMonochromeMode decides whether to render the TTY in full colour or monochrome
|
||||
IsMonochromeMode = false
|
||||
)
|
||||
|
||||
func setupTcell() {
|
||||
|
@ -39,39 +41,62 @@ func readStdin() {
|
|||
switch ev := ev.(type) {
|
||||
case *tcell.EventKey:
|
||||
handleUserKeyPress(ev)
|
||||
eventMap := map[string]interface{}{
|
||||
"key": int(ev.Key()),
|
||||
"char": string(ev.Rune()),
|
||||
"mod": int(ev.Modifiers()),
|
||||
}
|
||||
marshalled, _ := json.Marshal(eventMap)
|
||||
sendMessageToWebExtension("/stdin," + string(marshalled))
|
||||
case *tcell.EventResize:
|
||||
screen.Sync()
|
||||
sendTtySize()
|
||||
handleTTYResize()
|
||||
case *tcell.EventMouse:
|
||||
x, y := ev.Position()
|
||||
button := ev.Buttons()
|
||||
eventMap := map[string]interface{}{
|
||||
"button": int(button),
|
||||
"mouse_x": int(x + CurrentTab.frame.xScroll),
|
||||
"mouse_y": int(y - uiHeight + CurrentTab.frame.yScroll),
|
||||
"modifiers": int(ev.Modifiers()),
|
||||
}
|
||||
marshalled, _ := json.Marshal(eventMap)
|
||||
sendMessageToWebExtension("/stdin," + string(marshalled))
|
||||
handleMouseEvent(ev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleUserKeyPress(ev *tcell.EventKey) {
|
||||
if ev.Key() == tcell.KeyCtrlQ {
|
||||
if !*isUseExistingFirefox {
|
||||
quitFirefox()
|
||||
}
|
||||
Shutdown(errors.New("normal"))
|
||||
switch ev.Key() {
|
||||
case tcell.KeyCtrlQ:
|
||||
quitBrowsh()
|
||||
case tcell.KeyCtrlL:
|
||||
urlBarFocusToggle()
|
||||
}
|
||||
handleScrolling(ev)
|
||||
if (ev.Rune() == 'm' && ev.Modifiers() == 4) {
|
||||
toggleMonochromeMode()
|
||||
}
|
||||
forwardKeyPress(ev)
|
||||
if activeInputBox != nil {
|
||||
handleInputBoxInput(ev)
|
||||
} else {
|
||||
handleScrolling(ev) // TODO: shouldn't you be able to still use mouse scrolling?
|
||||
}
|
||||
}
|
||||
|
||||
func quitBrowsh() {
|
||||
if !*isUseExistingFirefox {
|
||||
quitFirefox()
|
||||
}
|
||||
Shutdown(errors.New("normal"))
|
||||
}
|
||||
|
||||
func urlBarFocusToggle() {
|
||||
if urlInputBox.isActive {
|
||||
activeInputBox = nil
|
||||
urlInputBox.isActive = false
|
||||
} else {
|
||||
activeInputBox = &urlInputBox
|
||||
urlInputBox.isActive = true
|
||||
urlInputBox.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
func toggleMonochromeMode() {
|
||||
IsMonochromeMode = !IsMonochromeMode
|
||||
}
|
||||
|
||||
func forwardKeyPress(ev *tcell.EventKey) {
|
||||
eventMap := map[string]interface{}{
|
||||
"key": int(ev.Key()),
|
||||
"char": string(ev.Rune()),
|
||||
"mod": int(ev.Modifiers()),
|
||||
}
|
||||
marshalled, _ := json.Marshal(eventMap)
|
||||
sendMessageToWebExtension("/stdin," + string(marshalled))
|
||||
}
|
||||
|
||||
func handleScrolling(ev *tcell.EventKey) {
|
||||
|
@ -96,18 +121,25 @@ func handleScrolling(ev *tcell.EventKey) {
|
|||
}
|
||||
}
|
||||
|
||||
// Write a simple text string to the screen. Not for use in the browser frames
|
||||
// themselves. If you want anything to appear in the browser that must be done
|
||||
// through the webextension.
|
||||
func writeString(x, y int, str string) {
|
||||
var defaultColours = tcell.StyleDefault
|
||||
rgb := tcell.NewHexColor(int32(0xffffff))
|
||||
defaultColours.Foreground(rgb)
|
||||
for _, c := range str {
|
||||
screen.SetContent(x, y, c, nil, defaultColours)
|
||||
x++
|
||||
func handleMouseEvent(ev *tcell.EventMouse) {
|
||||
x, y := ev.Position()
|
||||
button := ev.Buttons()
|
||||
eventMap := map[string]interface{}{
|
||||
"button": int(button),
|
||||
"mouse_x": int(x + CurrentTab.frame.xScroll),
|
||||
"mouse_y": int(y - uiHeight + CurrentTab.frame.yScroll),
|
||||
"modifiers": int(ev.Modifiers()),
|
||||
}
|
||||
screen.Show()
|
||||
marshalled, _ := json.Marshal(eventMap)
|
||||
sendMessageToWebExtension("/stdin," + string(marshalled))
|
||||
}
|
||||
|
||||
func handleTTYResize() {
|
||||
width, _ := screen.Size()
|
||||
// TODO: How does this work with wide UTF8 chars?
|
||||
urlInputBox.Width = width - len(urlBarControls)
|
||||
screen.Sync()
|
||||
sendTtySize()
|
||||
}
|
||||
|
||||
func renderAll() {
|
||||
|
@ -141,11 +173,19 @@ func renderCurrentTabWindow() {
|
|||
for x := 0; x < width; x++ {
|
||||
index = ((y + frame.yScroll) * frame.width) + ((x + frame.xScroll))
|
||||
if (!checkCell(index, x + frame.xScroll, y + frame.yScroll)) { return }
|
||||
styling = styling.Foreground(frame.cells[index].fgColour)
|
||||
styling = styling.Background(frame.cells[index].bgColour)
|
||||
runeChars = frame.cells[index].character
|
||||
// TODO: do this is in isCharacterTransparent()
|
||||
if (len(runeChars) == 0) { continue }
|
||||
if IsMonochromeMode {
|
||||
styling = styling.Foreground(tcell.ColorWhite)
|
||||
styling = styling.Background(tcell.ColorBlack)
|
||||
if runeChars[0] == '▄' {
|
||||
runeChars[0] = ' '
|
||||
}
|
||||
} else {
|
||||
styling = styling.Foreground(frame.cells[index].fgColour)
|
||||
styling = styling.Background(frame.cells[index].bgColour)
|
||||
}
|
||||
screen.SetCell(x, y + uiHeight, styling, runeChars[0])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,19 @@ package browsh
|
|||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
)
|
||||
|
||||
var (
|
||||
urlBarControls = " ← | x | "
|
||||
urlInputBox = inputBox{
|
||||
X: len(urlBarControls),
|
||||
Y: 1,
|
||||
Height: 1,
|
||||
text: "",
|
||||
}
|
||||
)
|
||||
// Render tabs, URL bar, status messages, etc
|
||||
func renderUI() {
|
||||
renderTabs()
|
||||
|
@ -11,6 +22,20 @@ func renderUI() {
|
|||
overlayPageStatusMessage()
|
||||
}
|
||||
|
||||
// Write a simple text string to the screen.
|
||||
// Not for use in the browser frames themselves. If you want anything to appear in
|
||||
// the browser that must be done through the webextension.
|
||||
func writeString(x, y int, str string) {
|
||||
var defaultColours = tcell.StyleDefault
|
||||
rgb := tcell.NewHexColor(int32(0xffffff))
|
||||
defaultColours.Foreground(rgb)
|
||||
for _, c := range str {
|
||||
screen.SetContent(x, y, c, nil, defaultColours)
|
||||
x++
|
||||
}
|
||||
screen.Show()
|
||||
}
|
||||
|
||||
func fillLineToEnd(x, y int) {
|
||||
width, _ := screen.Size()
|
||||
for i := x; i < width - 1; i++ {
|
||||
|
@ -34,9 +59,9 @@ func renderTabs() {
|
|||
}
|
||||
|
||||
func renderURLBar() {
|
||||
content := " ← | x | " + CurrentTab.URI
|
||||
content := urlBarControls + getCurrentURLBarContents()
|
||||
writeString(0, 1, content)
|
||||
fillLineToEnd(utf8.RuneCountInString(content) - 1, 0)
|
||||
fillLineToEnd(utf8.RuneCountInString(content), 1)
|
||||
}
|
||||
|
||||
func overlayPageStatusMessage() {
|
||||
|
@ -44,3 +69,12 @@ func overlayPageStatusMessage() {
|
|||
writeString(0, height - 1, CurrentTab.StatusMessage)
|
||||
}
|
||||
|
||||
func getCurrentURLBarContents() string {
|
||||
var contents string
|
||||
if urlInputBox.isActive {
|
||||
contents = urlInputBox.text
|
||||
} else {
|
||||
contents = CurrentTab.URI
|
||||
}
|
||||
return contents
|
||||
}
|
||||
|
|
|
@ -62,13 +62,22 @@ var _ = Describe("Showing a basic webpage", func() {
|
|||
})
|
||||
|
||||
It("should render dynamic content", func() {
|
||||
Expect([3]int32{0, 255, 255}).To(Equal(GetFgColour(39, 3)))
|
||||
waitForNextFrame()
|
||||
Expect([3]int32{255, 0, 255}).To(Equal(GetFgColour(39, 3)))
|
||||
var greens, pinks int
|
||||
var colours [10][3]int32
|
||||
for i := 0; i < 10; i++ {
|
||||
colours[i] = GetFgColour(39, 3)
|
||||
waitForNextFrame()
|
||||
}
|
||||
for i := 0; i < 10; i++ {
|
||||
if colours[i] == [3]int32{0, 255, 255} { greens++ }
|
||||
if colours[i] == [3]int32{255, 0, 255} { pinks++ }
|
||||
}
|
||||
Expect(greens).To(BeNumerically(">=", 1))
|
||||
Expect(pinks).To(BeNumerically(">=", 1))
|
||||
})
|
||||
|
||||
It("should switch to monochrome mode", func() {
|
||||
simScreen.InjectKey(tcell.KeyRune, 'M', tcell.ModAlt)
|
||||
simScreen.InjectKey(tcell.KeyRune, 'm', tcell.ModAlt)
|
||||
waitForNextFrame()
|
||||
Expect([3]int32{0, 0, 0}).To(Equal(GetBgColour(0, 2)))
|
||||
Expect([3]int32{255, 255, 255}).To(Equal(GetFgColour(12, 11)))
|
||||
|
|
|
@ -90,7 +90,7 @@ func WaitForPageLoad() {
|
|||
start := time.Now()
|
||||
for time.Since(start) < perTestTimeout {
|
||||
if browsh.CurrentTab.PageState == "parsing_complete" {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
@ -190,6 +190,7 @@ func runeCount(text string) int {
|
|||
}
|
||||
|
||||
var _ = ginkgo.BeforeEach(func() {
|
||||
browsh.IsMonochromeMode = false
|
||||
browsh.Log("\n---------")
|
||||
browsh.Log(ginkgo.CurrentGinkgoTestDescription().FullTestText)
|
||||
browsh.Log("---------")
|
||||
|
|
|
@ -163,14 +163,7 @@ export default class extends utils.mixins(CommonMixin) {
|
|||
}
|
||||
|
||||
_handleCharBasedKeys(input) {
|
||||
switch (input.char) {
|
||||
case 'M':
|
||||
if (input.mod === 4) {
|
||||
this.frame_builder.is_graphics_mode = !this.frame_builder.is_graphics_mode;
|
||||
this.frame_builder.buildText();
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (input.char) { default: }
|
||||
}
|
||||
|
||||
_handleMouse(input) {
|
||||
|
|
Loading…
Reference in a new issue