Moved URL bar input and mono mode toggle to CLI

Finally fixes integration tests
This commit is contained in:
Thomas Buckley-Houston 2018-04-28 19:02:40 +08:00
parent b605965e77
commit ae44a18cfc
8 changed files with 174 additions and 58 deletions

View file

@ -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:

View file

@ -1,4 +0,0 @@
#!/bin/bash
set -e
go test test/*.go -v

View 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()
}

View file

@ -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])
}
}

View file

@ -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
}

View file

@ -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)))

View file

@ -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("---------")

View file

@ -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) {