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)