From 527df8bb16abcaf60528f93a6f32d4ceb45a4680 Mon Sep 17 00:00:00 2001 From: Thomas Buckley-Houston Date: Mon, 16 Jul 2018 17:58:53 +0800 Subject: [PATCH] Fix for non-ASCII chars generating extra chars This was caused by misunderstanding of the finer details of strings, runes and slices. I just changed the input_box struct to use runes and then followed the trail of type errors until input_boxes only ever used strings to send their text outside themselves. Closes #93 --- interfacer/src/browsh/input_box.go | 18 ++++++------ interfacer/src/browsh/input_cursor.go | 29 +++++-------------- interfacer/src/browsh/input_multiline.go | 4 +-- interfacer/src/browsh/input_multiline_test.go | 2 +- interfacer/src/browsh/input_scroll.go | 10 +++---- interfacer/src/browsh/ui.go | 18 +++++------- 6 files changed, 32 insertions(+), 49 deletions(-) diff --git a/interfacer/src/browsh/input_box.go b/interfacer/src/browsh/input_box.go index 1e05ebd..b69010d 100644 --- a/interfacer/src/browsh/input_box.go +++ b/interfacer/src/browsh/input_box.go @@ -29,7 +29,7 @@ type inputBox struct { bgColour [3]int32 isActive bool multiLiner multiLine - text string + text []rune xCursor int yCursor int textCursor int @@ -79,7 +79,7 @@ func (i *inputBox) setCells() { } continue } - if i.Type == "password" && index != utf8.RuneCountInString(i.text) { + if i.Type == "password" && index != len(i.text) { c = '●' } i.addCharacterToFrame(x, y, c) @@ -145,7 +145,7 @@ func (i *inputBox) textToDisplay() []rune { func (i *inputBox) textToDisplayForSingleLine() []rune { var textToDisplay string index := 0 - for _, c := range i.text + " " { + for _, c := range append(i.text, ' ') { if index >= i.xScroll { textToDisplay += string(c) } @@ -168,7 +168,7 @@ func isLineBreak(character string) bool { func (i *inputBox) sendInputBoxToBrowser() { inputBoxMap := map[string]interface{}{ "id": i.ID, - "text": i.text, + "text": string(i.text), } marshalled, _ := json.Marshal(inputBoxMap) sendMessageToWebExtension("/tab_command,/input_box," + string(marshalled)) @@ -177,9 +177,9 @@ func (i *inputBox) sendInputBoxToBrowser() { func (i *inputBox) handleEnterKey(modifier tcell.ModMask) { if urlInputBox.isActive { if isNewEmptyTabActive() { - sendMessageToWebExtension("/new_tab," + i.text) + sendMessageToWebExtension("/new_tab," + string(i.text)) } else { - sendMessageToWebExtension("/url_bar," + i.text) + sendMessageToWebExtension("/url_bar," + string(i.text)) } urlBarFocus(false) } @@ -189,7 +189,7 @@ func (i *inputBox) handleEnterKey(modifier tcell.ModMask) { i.isActive = false } if i.isMultiLine() && modifier == tcell.ModAlt { - i.text = "" + i.text = nil i.isActive = true } i.updateAllCursors() @@ -202,7 +202,7 @@ func (i *inputBox) selectionOff() { func (i *inputBox) selectAll() { urlInputBox.selectionStart = 0 - urlInputBox.selectionEnd = utf8.RuneCountInString(urlInputBox.text) + urlInputBox.selectionEnd = len(urlInputBox.text) } func (i *inputBox) removeSelectedText() { @@ -211,7 +211,7 @@ func (i *inputBox) removeSelectedText() { } start := i.text[:i.selectionStart] end := i.text[i.selectionEnd:] - i.text = start + end + i.text = append(start, end...) i.textCursor = i.selectionStart i.updateXYCursors() activeInputBox.selectionOff() diff --git a/interfacer/src/browsh/input_cursor.go b/interfacer/src/browsh/input_cursor.go index 98fe00a..130441c 100644 --- a/interfacer/src/browsh/input_cursor.go +++ b/interfacer/src/browsh/input_cursor.go @@ -1,7 +1,5 @@ package browsh -import "unicode/utf8" - func (i *inputBox) renderCursor() { if !i.isActive { return @@ -24,7 +22,7 @@ func (i *inputBox) renderSingleCursor() { func (i *inputBox) renderSelectionCursor() { var x, y int - textLength := utf8.RuneCountInString(i.text) + textLength := len(i.text) for index := 0; index < textLength; index++ { x, y = i.getCoordsOfIndex(index) if x >= i.selectionStart && x < i.selectionEnd { @@ -78,7 +76,7 @@ func (i *inputBox) cursorDown() { } func (i *inputBox) cursorBackspace() { - if utf8.RuneCountInString(i.text) == 0 { + if len(i.text) == 0 { return } if i.textCursor == 0 { @@ -86,16 +84,16 @@ func (i *inputBox) cursorBackspace() { } start := i.text[:i.textCursor-1] end := i.text[i.textCursor:] - i.text = start + end + i.text = append(start, end...) i.cursorLeft() i.sendInputBoxToBrowser() } func (i *inputBox) cursorInsertRune(theRune rune) { - character := string(theRune) start := i.text[:i.textCursor] end := i.text[i.textCursor:] - i.text = start + character + end + endWithRune := append([]rune{theRune}, end...) + i.text = append(start, endWithRune...) i.cursorRight() i.sendInputBoxToBrowser() } @@ -116,19 +114,8 @@ func (i *inputBox) isCursorOverBottomEdge() bool { return i.yCursor-i.yScroll > i.Height } -func (i *inputBox) getCharacterAt() string { - var index int - var c rune - for index, c = range i.text { - if index == i.textCursor { - return string(c) - } - } - return "" -} - func (i *inputBox) putCursorAtEnd() { - i.textCursor = utf8.RuneCountInString(urlInputBox.text) + i.textCursor = len(urlInputBox.text) // TODO: Do for multiline } @@ -154,8 +141,8 @@ func (i *inputBox) limitTextCursor() { if i.textCursor < 0 { i.textCursor = 0 } - if i.textCursor > utf8.RuneCountInString(i.text) { - i.textCursor = utf8.RuneCountInString(i.text) + if i.textCursor > len(i.text) { + i.textCursor = len(i.text) } } diff --git a/interfacer/src/browsh/input_multiline.go b/interfacer/src/browsh/input_multiline.go index e123dcc..d7696b5 100644 --- a/interfacer/src/browsh/input_multiline.go +++ b/interfacer/src/browsh/input_multiline.go @@ -20,7 +20,7 @@ type multiLine struct { func (m *multiLine) convert() []rune { var aRune rune m.reset() - for m.index, aRune = range m.inputBox.text + " " { + for m.index, aRune = range append(m.inputBox.text, ' ') { m.previousCharacter = m.currentCharacter m.currentCharacter = string(aRune) if m.isWordishReady() { @@ -153,7 +153,7 @@ func (m *multiLine) isNaturalLineBreak() bool { } func (m *multiLine) isFinalCharacter() bool { - return m.index+1 == utf8.RuneCountInString(m.inputBox.text)+1 + return m.index+1 == len(m.inputBox.text)+1 } func (m *multiLine) lineCount() int { diff --git a/interfacer/src/browsh/input_multiline_test.go b/interfacer/src/browsh/input_multiline_test.go index dbe53f5..cda3186 100644 --- a/interfacer/src/browsh/input_multiline_test.go +++ b/interfacer/src/browsh/input_multiline_test.go @@ -17,7 +17,7 @@ var input *inputBox func toMulti(text string, width int) string { input = newInputBox("0") - input.text = text + input.text = []rune(text) input.Width = width input.TagName = "TEXTAREA" textRunes := input.multiLiner.convert() diff --git a/interfacer/src/browsh/input_scroll.go b/interfacer/src/browsh/input_scroll.go index 8639713..67f448a 100644 --- a/interfacer/src/browsh/input_scroll.go +++ b/interfacer/src/browsh/input_scroll.go @@ -1,7 +1,5 @@ package browsh -import "unicode/utf8" - func (i *inputBox) xScrollBy(magnitude int) { if !i.isMultiLine() { i.handleSingleLineScroll(magnitude) @@ -17,7 +15,7 @@ func (i *inputBox) yScrollBy(magnitude int) { } func (i *inputBox) handleSingleLineScroll(magnitude int) { - detectionTextWidth := utf8.RuneCountInString(i.text) + detectionTextWidth := len(i.text) detectionBoxWidth := i.Width if magnitude < 0 { detectionTextWidth++ @@ -38,7 +36,7 @@ func (i *inputBox) isCursorAtEdgeOfBox(detectionBoxWidth int) bool { } func (i *inputBox) isBestFit() bool { - lengthOfVisibleText := utf8.RuneCountInString(i.text) - i.xScroll + lengthOfVisibleText := len(i.text) - i.xScroll return lengthOfVisibleText >= i.Width } @@ -48,8 +46,8 @@ func (i *inputBox) limitScroll() { if i.xScroll < 0 { i.xScroll = 0 } - if i.xScroll > utf8.RuneCountInString(i.text) { - i.xScroll = utf8.RuneCountInString(i.text) + if i.xScroll > len(i.text) { + i.xScroll = len(i.text) } if i.isMultiLine() { if i.yScroll < 0 { diff --git a/interfacer/src/browsh/ui.go b/interfacer/src/browsh/ui.go index d14d634..543cb41 100644 --- a/interfacer/src/browsh/ui.go +++ b/interfacer/src/browsh/ui.go @@ -1,8 +1,6 @@ package browsh import ( - "unicode/utf8" - "github.com/gdamore/tcell" ) @@ -11,7 +9,7 @@ var ( X: 0, Y: 1, Height: 1, - text: "", + text: nil, FgColour: [3]int32{255, 255, 255}, bgColour: [3]int32{-1, -1, -1}, } @@ -75,16 +73,16 @@ func renderTabs() { } func renderURLBar() { - var content string + var content []rune if urlInputBox.isActive { - writeString(0, 1, content, tcell.StyleDefault) - content += urlInputBox.text + " " + writeString(0, 1, string(content), tcell.StyleDefault) + content = append(urlInputBox.text, ' ') urlInputBox.renderURLBox() } else { - content += CurrentTab.URI - writeString(0, 1, content, tcell.StyleDefault) + content = []rune(CurrentTab.URI) + writeString(0, 1, string(content), tcell.StyleDefault) } - fillLineToEnd(utf8.RuneCountInString(content), 1) + fillLineToEnd(len(content), 1) } func urlBarFocusToggle() { @@ -104,7 +102,7 @@ func urlBarFocus(on bool) { activeInputBox = &urlInputBox urlInputBox.isActive = true urlInputBox.xScroll = 0 - urlInputBox.text = CurrentTab.URI + urlInputBox.text = []rune(CurrentTab.URI) urlInputBox.putCursorAtEnd() urlInputBox.selectAll() }