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,37 +27,42 @@ ...@@ -18,37 +27,42 @@
.editor .editor
display: flex display: flex
width: 100% width: 100%
.code .code-area
flex-grow: 1 flex-grow: 1
height: 500px max-height: 200px
position: relative overflow: auto
font-family: Fira code,Fira Mono,Consolas,Menlo,Courier,monospace .code-container
font-size: 12px background-color: #fafafa
font-variant-ligatures: common-ligatures box-sizing: border-box
line-height: 1.5
textarea
border: 0px
margin: 0px
padding: 10px
position: absolute
left: 0px
top: 0px
resize: none
height: 100%
width: 100%
overflow: hidden
-webkit-text-fill-color: transparent
@include font-inherit()
code
background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%
border: 0px none
margin: 0px
padding: 10px
color: #000
display: block
pointer-events: none
position: relative position: relative
@include font-inherit() font-family: Fira code,Fira Mono,Consolas,Menlo,Courier,monospace
font-size: 12px
font-variant-ligatures: common-ligatures
line-height: 1.5
overflow: hidden
padding: 0px
text-align: left
textarea
border: 0px
color: inherit
position: absolute
left: 0px
top: 0px
resize: none
height: 100%
overflow: hidden
width: 100%
-webkit-text-fill-color: transparent
@include common-overlay-props()
@include font-inherit()
pre
background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%
border: 0px none
color: #000
pointer-events: none
position: relative
@include common-overlay-props()
@include font-inherit()
.v-divider .v-divider
border-left: 1px solid gray border-left: 1px solid gray
cursor: sw-resize cursor: sw-resize
......
...@@ -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,13 +98,8 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -91,13 +98,8 @@ 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 pure $ pure unit
Nothing -> pure $ pure unit
Just codeOverlayEl -> do
_ <- pure $ (codeOverlayEl .= "innerText") code
HLJS.highlightBlock codeOverlayEl
pure $ pure unit
pure $ H.div { className: "code-editor" } [ pure $ H.div { className: "code-editor" } [
toolbar controls toolbar controls
...@@ -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.textarea { defaultValue: code H.div { className: "code-container" } [
, on: { change: onEditChange controls } H.textarea { defaultValue: code
, ref: controls.codeElRef } [ ] , on: { change: onEditChange controls }
, H.code { className: "" , placeholder: "Type some code..."
-- , contentEditable: "true" , ref: controls.codeElRef } [ ]
, ref: controls.codeOverlayElRef , H.pre { className: ""
, rows: 30 -- , contentEditable: "true"
--, on: { input: onEditChange (fst codeType) codeElRef htmlRef editorCodeRef error } , ref: controls.codeOverlayElRef
} [] , rows: 30
] --, 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,23 +144,22 @@ codeEditorCpt = R.hooksComponent "G.C.CE.CodeEditor" cpt ...@@ -139,23 +144,22 @@ 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 code = R2.unsafeEventValue e
let mCodeOverlayEl = toMaybe $ R.readRef codeOverlayElRef R.setRef editorCodeRef code
case mCodeOverlayEl of setCodeOverlay controls code
Nothing -> log "[onChange] mCodeOverlayEl = Nothing"
Just codeOverlayEl -> do
--R.setRef editorCodeRef $ R2.innerText codeOverlayEl
let code = R2.unsafeEventValue e
R.setRef editorCodeRef code
_ <- case (toMaybe $ R.readRef codeElRef) of
Nothing -> pure unit
Just codeEl -> do
_ <- pure $ (codeOverlayEl .= "innerText") code
HLJS.highlightBlock codeOverlayEl
pure unit
pure unit
renderHtml (R.readRef controls.editorCodeRef) controls 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
Just codeOverlayEl -> do
_ <- pure $ (codeOverlayEl .= "innerText") $ codeNlFix codeType code
HLJS.highlightBlock codeOverlayEl
pure unit
pure unit
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)} =
case (toMaybe $ R.readRef htmlElRef) of case (toMaybe $ R.readRef htmlElRef) of
......
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