1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module Gargantext.Utils.Selection where
import Prelude
import Data.Maybe (Maybe, maybe)
import Data.Nullable (Nullable, toMaybe)
import DOM.Simple.Types (Element, DOMRect)
import DOM.Simple.Element as Element
import Effect (Effect)
import FFI.Simple ((.?), (..), (...))
-- | Represents a text selection
foreign import data Selection :: Type
-- | Represents a single selection range
foreign import data Range :: Type
-- Terminology:
-- Anchor: point at which the selection was started
-- Focus: point at which the selection ends
-- | The Node in which the anchor lies
anchorNode :: Selection -> Maybe Element
anchorNode s = s .? "anchorNode"
-- | The Node in which the focus lies
focusNode :: Selection -> Maybe Element
focusNode s = s .? "focusNode"
-- | 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]
-- | Renders a selection or range as a string
selectionToString :: Selection -> String
selectionToString s = s ... "toString" $ []
-- | Renders a range as a string
rangeToString :: Range -> String
rangeToString s = s ... "toString" $ []
-- | 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
-- | Fetches the current text selection, if any
getSelection :: Effect (Maybe Selection)
getSelection = toMaybe <$> _getSelection
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)