Selection.purs 2.39 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 4
import Prelude
import Data.Maybe (Maybe, fromMaybe, maybe)
5
import Data.Nullable (Nullable, toMaybe)
James Laver's avatar
James Laver committed
6 7
import DOM.Simple.Types (Element, DOMRect)
import DOM.Simple.Element as Element
8
import Effect (Effect)
James Laver's avatar
James Laver committed
9
import FFI.Simple ((.?), (..), (...))
10 11 12

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

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

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

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

James Laver's avatar
James Laver committed
28 29 30 31 32 33 34 35 36
-- | 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]
37 38

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

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

James Laver's avatar
James Laver committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
-- | 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
66 67 68 69 70

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

James Laver's avatar
James Laver committed
71 72 73 74 75 76 77 78
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)