Selection.purs 2.54 KB
Newer Older
James Laver's avatar
James Laver committed
1
module Gargantext.Utils.Selection where
2

James Laver's avatar
James Laver committed
3
import Prelude
4
import Data.Maybe (Maybe, maybe)
5
import Data.Nullable (Nullable, toMaybe)
6
import Data.Tuple (Tuple(..))
James Laver's avatar
James Laver committed
7 8
import DOM.Simple.Types (Element, DOMRect)
import DOM.Simple.Element as Element
9
import Effect (Effect)
James Laver's avatar
James Laver committed
10
import FFI.Simple ((.?), (..), (...))
11 12 13

-- | Represents a text selection
foreign import data Selection :: Type
James Laver's avatar
James Laver committed
14 15
-- | Represents a single selection range
foreign import data Range :: Type
16

James Laver's avatar
James Laver committed
17 18 19
-- Terminology:
  -- Anchor: point at which the selection was started
  -- Focus: point at which the selection ends
20

James Laver's avatar
James Laver committed
21 22 23
-- | The Node in which the anchor lies
anchorNode :: Selection -> Maybe Element
anchorNode s = s .? "anchorNode"
24

James Laver's avatar
James Laver committed
25 26 27
-- | The Node in which the focus lies
focusNode :: Selection -> Maybe Element
focusNode s = s .? "focusNode"
28

James Laver's avatar
James Laver committed
29 30 31 32 33 34 35 36 37
-- | Whether the anchor and focus are at the same point
isSelectionCollapsed :: Selection -> Boolean
isSelectionCollapsed s = s .. "isCollapsed"

rangeCount :: Selection -> Int
rangeCount s = s .. "rangeCount"

getRange :: Selection -> Int -> Effect Range
getRange s i = pure $ s ... "getRangeAt" $ [i]
38 39

-- | Renders a selection or range as a string
James Laver's avatar
James Laver committed
40 41
selectionToString :: Selection -> String
selectionToString s = s ... "toString" $ []
42

James Laver's avatar
James Laver committed
43 44 45
-- | Renders a range as a string
rangeToString :: Range -> String
rangeToString s = s ... "toString" $ []
46

47 48 49 50
--- | Convert range to an offset tuple
rangeToTuple :: Range -> Tuple Int Int
rangeToTuple r = Tuple (r .. "startOffset") (r .. "endOffset")

James Laver's avatar
James Laver committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
-- | Whether the anchor and focus are at the same point
isRangeCollapsed :: Range -> Boolean
isRangeCollapsed r = r .. "isCollapsed"

cloneRange :: Range -> Range
cloneRange r = r ... "cloneRange" $ []

collapseRange :: Range -> Boolean -> Effect Unit
collapseRange r toStart = pure $ r ... "collapse" $ [toStart]

commonAncestorContainer :: Range -> Element
commonAncestorContainer r = r .. "commonAncestorContainer"

insertNode :: Range -> Element -> Effect Unit
insertNode r e = pure $ r ... "insertNode" $ [e]

boundingRect :: Range -> DOMRect
boundingRect r = r ... "getBoundingClientRect" $ []

-- getSelection
71 72 73 74 75

-- | Fetches the current text selection, if any
getSelection :: Effect (Maybe Selection)
getSelection = toMaybe <$> _getSelection

James Laver's avatar
James Laver committed
76 77 78 79 80 81 82 83
foreign import _getSelection :: Effect (Nullable Selection)

-- | Are both the start and end of the selection contained within an Element
doesSelectionLieWithin :: Selection -> Element -> Boolean
doesSelectionLieWithin sel elem = test anchorNode && test focusNode
  where
    test :: (Selection -> Maybe Element) -> Boolean
    test f = maybe false (Element.contains elem) (f sel)