Skip to content

Commit

Permalink
Refactor handleEditorContentChanged for readability.
Browse files Browse the repository at this point in the history
Fix bug where error position highlight is not removed when content changes.
  • Loading branch information
maxhallinan committed Oct 3, 2019
1 parent 5d0e443 commit c7ac268
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 15 deletions.
36 changes: 24 additions & 12 deletions src/Component/Node.purs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import Halogen.HTML.Events as HE
import Halogen.HTML.Properties as HP
import Halogen.Query.EventSource as ES
import Parse as Parse
import Web.DOM.Node (setTextContent, textContent)
import Web.DOM.Node as Node
import Web.Event.Event (Event, EventType(..), preventDefault, stopPropagation)
import Web.Event.Event as Event
Expand Down Expand Up @@ -361,16 +360,28 @@ handleEditorKeyDown editorKey event = do

handleEditorContentChanged :: Event -> H.HalogenM State Action ChildSlots Message Aff Unit
handleEditorContentChanged event = do
let target = Event.target event >>= Node.fromEventTarget
case target of
Just t -> do
pendingContent <- H.liftEffect $ textContent t
H.modify_ \state -> state{ editorState = updatePendingContent pendingContent state.editorState }
if pendingContent == ""
then H.liftEffect $ Util.setLineBreak t
else pure unit
Nothing -> do
pure unit
getEditorNode # traverse_ \node -> do
pendingContent <- getPendingContent node
deleteEditorContentIfEmpty pendingContent node
removeHighlightIfErr pendingContent node
updateEditorState pendingContent
where getEditorNode = Event.target event >>= Node.fromEventTarget
getPendingContent = H.liftEffect <<< Node.textContent
updateEditorState content = H.modify_ \state -> state{ editorState = updatePendingContent content state.editorState }
deleteEditorContentIfEmpty content node =
if content == ""
then H.liftEffect $ Util.deleteEditorContent node
else pure unit
removeHighlightIfErr content node =
H.gets (getParseErr <<< _.editorState) >>= traverse_ \_ ->
H.liftEffect $ Util.setEditorTextContent content node

getParseErr :: EditorState -> Maybe Parse.ParseErr
getParseErr = case _ of
Read ->
Nothing
Write editor ->
editor.parseErr

updatePendingContent :: String -> EditorState -> EditorState
updatePendingContent pendingContent editorState =
Expand Down Expand Up @@ -415,9 +426,10 @@ handleEditBtnClicked event = do
bindEditorEvents element
where setEditorFocus = H.gets getAstId >>= setFocus
setEditorWriteState = H.modify_ \state -> state{ editorState = Write { parseErr: Nothing, pendingContent: "" } }
setTextContent textContent node = H.liftEffect $ Node.setTextContent textContent node
setEditorTextContent element = do
ast <- H.gets _.ast
H.liftEffect $ setTextContent (show ast.expr) (HTMLElement.toNode element)
setTextContent (show ast.expr) (HTMLElement.toNode element)
getEditorElement = H.getHTMLElementRef editorRef
bindEditorEvents element = do
let eventTarget = HTMLElement.toEventTarget element
Expand Down
2 changes: 1 addition & 1 deletion src/Component/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ exports._setEditorTextContent = function (textContent, node) {
var anchorNode = selection.anchorNode;
node.textContent = textContent;
try {
selection.setPosition(anchorNode, anchorOffset);
selection.setPosition(node.childNodes[0], anchorOffset);
} catch (error) {
selection.setPosition(node.childNodes[0], 0);
}
Expand Down
8 changes: 6 additions & 2 deletions src/Component/Util.purs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ module Component.Util
, setFocus
, setSelectionRange
, setLineBreak

, deleteEditorContent
, highlightErrPos
, setEditorTextContent
) where

import Prelude
Expand Down Expand Up @@ -62,8 +66,8 @@ foreign import _setLineBreak :: EU.EffectFn1 DOM.Node Unit
deleteEditorContent :: DOM.Node -> Effect Unit
deleteEditorContent = EU.runEffectFn1 _deleteEditorContent

highlightErPos :: { before :: String, highlight :: String, after :: String } -> DOM.Node -> Effect Unit
highlightErPos = EU.runEffectFn2 _highlightErrPos
highlightErrPos :: { before :: String, highlight :: String, after :: String } -> DOM.Node -> Effect Unit
highlightErrPos = EU.runEffectFn2 _highlightErrPos

setEditorTextContent :: String -> DOM.Node -> Effect Unit
setEditorTextContent = EU.runEffectFn2 _setEditorTextContent
Expand Down

0 comments on commit c7ac268

Please sign in to comment.