Commit c670fc65 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[CodeEditor] newline fix for markdown, some more refactoring

parent 933eb246
...@@ -7,27 +7,41 @@ ...@@ -7,27 +7,41 @@
display: flex; display: flex;
width: 100%; width: 100%;
} }
.code-editor .editor .code { .code-editor .editor .code-area {
flex-grow: 1; flex-grow: 1;
height: 500px; max-height: 200px;
overflow: auto;
}
.code-editor .editor .code-area .code-container {
background-color: #fafafa;
box-sizing: border-box;
position: relative; position: relative;
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace; font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
font-size: 12px; font-size: 12px;
font-variant-ligatures: common-ligatures; font-variant-ligatures: common-ligatures;
line-height: 1.5; line-height: 1.5;
overflow: hidden;
padding: 0px;
text-align: left;
} }
.code-editor .editor .code textarea { .code-editor .editor .code-area .code-container textarea {
border: 0px; border: 0px;
margin: 0px; color: inherit;
padding: 10px;
position: absolute; position: absolute;
left: 0px; left: 0px;
top: 0px; top: 0px;
resize: none; resize: none;
height: 100%; height: 100%;
width: 100%;
overflow: hidden; overflow: hidden;
width: 100%;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
box-sizing: inherit;
display: inherit;
margin: 0px;
padding: 10px;
overflow-wrap: break-word;
white-space: pre-wrap;
word-break: keep-all;
font-family: inherit; font-family: inherit;
font-size: inherit; font-size: inherit;
font-style: inherit; font-style: inherit;
...@@ -39,15 +53,19 @@ ...@@ -39,15 +53,19 @@
text-rendering: inherit; text-rendering: inherit;
text-transform: inherit; text-transform: inherit;
} }
.code-editor .editor .code code { .code-editor .editor .code-area .code-container pre {
background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%; background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%;
border: 0px none; border: 0px none;
margin: 0px;
padding: 10px;
color: #000; color: #000;
display: block;
pointer-events: none; pointer-events: none;
position: relative; position: relative;
box-sizing: inherit;
display: inherit;
margin: 0px;
padding: 10px;
overflow-wrap: break-word;
white-space: pre-wrap;
word-break: keep-all;
font-family: inherit; font-family: inherit;
font-size: inherit; font-size: inherit;
font-style: inherit; font-style: inherit;
......
...@@ -10,6 +10,15 @@ ...@@ -10,6 +10,15 @@
text-rendering: inherit text-rendering: inherit
text-transform: inherit text-transform: inherit
@mixin common-overlay-props()
box-sizing: inherit
display: inherit
margin: 0px
padding: 10px
overflow-wrap: break-word
white-space: pre-wrap
word-break: keep-all
.code-editor .code-editor
.toolbar .toolbar
display: flex display: flex
...@@ -18,36 +27,41 @@ ...@@ -18,36 +27,41 @@
.editor .editor
display: flex display: flex
width: 100% width: 100%
.code .code-area
flex-grow: 1 flex-grow: 1
height: 500px max-height: 200px
overflow: auto
.code-container
background-color: #fafafa
box-sizing: border-box
position: relative position: relative
font-family: Fira code,Fira Mono,Consolas,Menlo,Courier,monospace font-family: Fira code,Fira Mono,Consolas,Menlo,Courier,monospace
font-size: 12px font-size: 12px
font-variant-ligatures: common-ligatures font-variant-ligatures: common-ligatures
line-height: 1.5 line-height: 1.5
overflow: hidden
padding: 0px
text-align: left
textarea textarea
border: 0px border: 0px
margin: 0px color: inherit
padding: 10px
position: absolute position: absolute
left: 0px left: 0px
top: 0px top: 0px
resize: none resize: none
height: 100% height: 100%
width: 100%
overflow: hidden overflow: hidden
width: 100%
-webkit-text-fill-color: transparent -webkit-text-fill-color: transparent
@include common-overlay-props()
@include font-inherit() @include font-inherit()
code pre
background: rgba(0, 0, 0, 0) none repeat scroll 0% 0% background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%
border: 0px none border: 0px none
margin: 0px
padding: 10px
color: #000 color: #000
display: block
pointer-events: none pointer-events: none
position: relative position: relative
@include common-overlay-props()
@include font-inherit() @include font-inherit()
.v-divider .v-divider
border-left: 1px solid gray border-left: 1px solid gray
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
"spec-quickcheck", "spec-quickcheck",
"string-parsers", "string-parsers",
"strings", "strings",
"stringutils",
"thermite", "thermite",
"tuples-native", "tuples-native",
"uint", "uint",
......
...@@ -7,9 +7,9 @@ import Data.Generic.Rep.Eq (genericEq) ...@@ -7,9 +7,9 @@ import Data.Generic.Rep.Eq (genericEq)
import Data.Generic.Rep.Show (genericShow) import Data.Generic.Rep.Show (genericShow)
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable, null, toMaybe) import Data.Nullable (Nullable, null, toMaybe)
import Data.String.Utils (endsWith)
import Data.Tuple (fst) import Data.Tuple (fst)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log, log2)
import DOM.Simple.Types (Element) import DOM.Simple.Types (Element)
import Effect (Effect) import Effect (Effect)
import FFI.Simple ((.=), delay) import FFI.Simple ((.=), delay)
...@@ -48,14 +48,21 @@ type Props = ...@@ -48,14 +48,21 @@ type Props =
, onChange :: String -> Effect Unit , onChange :: String -> Effect Unit
) )
-- Fixes newlines in code
-- This is useful eg for proper rendering of the textarea overlay
codeNlFix :: CodeType -> Code -> Code
codeNlFix Markdown "" = " "
codeNlFix Markdown c = if endsWith "\n" c then (c <> " ") else c
codeNlFix _ c = c
compile :: CodeType -> Code -> Either Error Html compile :: CodeType -> Code -> Either Error Html
compile JSON code = result compile JSON code = result
where where
parsedE = jsonParser code parsedE = jsonParser code
result = case parsedE of result = case parsedE of
Left err -> Left err Left err -> Left err
Right parsed -> Right $ "<pre>" <> (R2.stringify parsed 2) <> "</pre>" Right parsed -> Right $ R2.stringify parsed 2
compile Markdown code = Right $ compileMd code compile Markdown code = Right $ compileMd $ codeNlFix Markdown code
-- TODO Replace with markdown-it? -- TODO Replace with markdown-it?
-- https://pursuit.purescript.org/packages/purescript-markdown-it -- https://pursuit.purescript.org/packages/purescript-markdown-it
...@@ -91,12 +98,7 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -91,12 +98,7 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
pure $ pure unit pure $ pure unit
R.useEffectOnce $ delay unit $ \_ -> do R.useEffectOnce $ delay unit $ \_ -> do
let mCodeOverlayEl = toMaybe $ R.readRef controls.codeOverlayElRef _ <- setCodeOverlay controls code
case mCodeOverlayEl of
Nothing -> pure $ pure unit
Just codeOverlayEl -> do
_ <- pure $ (codeOverlayEl .= "innerText") code
HLJS.highlightBlock codeOverlayEl
pure $ pure unit pure $ pure unit
pure $ H.div { className: "code-editor" } [ pure $ H.div { className: "code-editor" } [
...@@ -105,17 +107,20 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -105,17 +107,20 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
errorComponent {error: controls.error} errorComponent {error: controls.error}
] ]
, H.div { className: "row editor" } [ , H.div { className: "row editor" } [
H.div { className: "code " <> (codeHidden $ fst controls.viewType) } [ H.div { className: "code-area " <> (codeHidden $ fst controls.viewType) } [
H.div { className: "code-container" } [
H.textarea { defaultValue: code H.textarea { defaultValue: code
, on: { change: onEditChange controls } , on: { change: onEditChange controls }
, placeholder: "Type some code..."
, ref: controls.codeElRef } [ ] , ref: controls.codeElRef } [ ]
, H.code { className: "" , H.pre { className: ""
-- , contentEditable: "true" -- , contentEditable: "true"
, ref: controls.codeOverlayElRef , ref: controls.codeOverlayElRef
, rows: 30 , rows: 30
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef editorCodeRef error } --, on: { input: onEditChange (fst codeType) codeElRef htmlRef editorCodeRef error }
} [] } []
] ]
]
, H.div { className: "v-divider " <> (dividerHidden $ fst controls.viewType) } [ H.text " " ] , H.div { className: "v-divider " <> (dividerHidden $ fst controls.viewType) } [ H.text " " ]
, H.div { className: "html " <> (previewHidden $ fst controls.viewType) , H.div { className: "html " <> (previewHidden $ fst controls.viewType)
, ref: controls.htmlElRef , ref: controls.htmlElRef
...@@ -139,22 +144,21 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -139,22 +144,21 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt
onEditChange :: forall e. Record Controls -> e -> Effect Unit onEditChange :: forall e. Record Controls -> e -> Effect Unit
onEditChange controls@{codeElRef, codeOverlayElRef, editorCodeRef} e = do onEditChange controls@{codeElRef, codeOverlayElRef, editorCodeRef} e = do
log2 "[onChange] e" e
let mCodeOverlayEl = toMaybe $ R.readRef codeOverlayElRef
case mCodeOverlayEl of
Nothing -> log "[onChange] mCodeOverlayEl = Nothing"
Just codeOverlayEl -> do
--R.setRef editorCodeRef $ R2.innerText codeOverlayEl
let code = R2.unsafeEventValue e let code = R2.unsafeEventValue e
R.setRef editorCodeRef code R.setRef editorCodeRef code
_ <- case (toMaybe $ R.readRef codeElRef) of setCodeOverlay controls code
renderHtml (R.readRef controls.editorCodeRef) controls
setCodeOverlay :: Record Controls -> Code -> Effect Unit
setCodeOverlay {codeOverlayElRef, codeType: (codeType /\ _)} code = do
let mCodeOverlayEl = toMaybe $ R.readRef codeOverlayElRef
_ <- case mCodeOverlayEl of
Nothing -> pure unit Nothing -> pure unit
Just codeEl -> do Just codeOverlayEl -> do
_ <- pure $ (codeOverlayEl .= "innerText") code _ <- pure $ (codeOverlayEl .= "innerText") $ codeNlFix codeType code
HLJS.highlightBlock codeOverlayEl HLJS.highlightBlock codeOverlayEl
pure unit pure unit
pure unit pure unit
renderHtml (R.readRef controls.editorCodeRef) controls
renderHtml :: Code -> Record Controls -> Effect Unit renderHtml :: Code -> Record Controls -> Effect Unit
renderHtml code {codeType: (codeType /\ _), htmlElRef, error: (_ /\ setError)} = renderHtml code {codeType: (codeType /\ _), htmlElRef, error: (_ /\ setError)} =
......
module Gargantext.Components.Forest.Tree.Node.Action.Upload where module Gargantext.Components.Forest.Tree.Node.Action.Upload where
import Prelude (class Show, Unit, const, discard, map, pure, show, ($), (<>), bind, void) import Prelude (class Show, Unit, bind, const, discard, map, pure, show, void, ($))
import Data.Maybe (Maybe(..), fromJust) import Data.Maybe (Maybe(..), fromJust)
import Data.Newtype (class Newtype) import Data.Newtype (class Newtype)
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
...@@ -12,13 +12,12 @@ import React.SyntheticEvent as E ...@@ -12,13 +12,12 @@ import React.SyntheticEvent as E
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import URI.Extra.QueryPairs as QP import URI.Extra.QueryPairs as QP
import URI.Query as Q
import Web.File.FileReader.Aff (readAsText) import Web.File.FileReader.Aff (readAsText)
import Gargantext.Components.Forest.Tree.Node.Action import Gargantext.Components.Forest.Tree.Node.Action
import Gargantext.Routes (SessionRoute(..)) import Gargantext.Routes (SessionRoute(..))
import Gargantext.Sessions (Session, postWwwUrlencoded, postMultipartFormData) import Gargantext.Sessions (Session, postWwwUrlencoded)
import Gargantext.Types (class ToQuery, toQuery, NodeType(..), AsyncTask(..)) import Gargantext.Types (class ToQuery, AsyncTask, NodeType(..))
import Gargantext.Utils (id) import Gargantext.Utils (id)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
......
...@@ -20,7 +20,7 @@ import Gargantext.Ends (Frontends, url) ...@@ -20,7 +20,7 @@ import Gargantext.Ends (Frontends, url)
import Gargantext.Routes (AppRoute) import Gargantext.Routes (AppRoute)
import Gargantext.Routes as Routes import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId) import Gargantext.Sessions (Session, sessionId)
import Gargantext.Types (NodeType(..), NodePath(..), fldr, AsyncTask(..)) import Gargantext.Types (AsyncTask, NodePath(..), NodeType(..), fldr)
import Gargantext.Utils (glyphicon, glyphiconActive) import Gargantext.Utils (glyphicon, glyphiconActive)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Prelude (Unit, bind, const, discard, identity, map, pure, show, void, ($), (<>), (==), (-), (+)) import Prelude (Unit, bind, const, discard, identity, map, pure, show, void, ($), (<>), (==), (-), (+))
......
...@@ -15,7 +15,6 @@ import Data.Tuple (fst, snd) ...@@ -15,7 +15,6 @@ import Data.Tuple (fst, snd)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff, launchAff_) import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect)
import Partial.Unsafe (unsafePartial) import Partial.Unsafe (unsafePartial)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as RH import Reactix.DOM.HTML as RH
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment