module Gargantext.Utils.Selection where import Prelude import Data.Maybe (Maybe, maybe) import Data.Nullable (Nullable, toMaybe) import Data.Tuple (Tuple(..)) 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" $ [] --- | Convert range to an offset tuple rangeToTuple :: Range -> Tuple Int Int rangeToTuple r = Tuple (r .. "startOffset") (r .. "endOffset") -- | 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)