| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- module LinkedIn where
- import Prelude
- import Data.List.NonEmpty as NEL
- import Data.List.Types (NonEmptyList)
- import Data.Maybe (Maybe(..))
- import Data.Traversable (traverse)
- import Effect (Effect)
- import LinkedIn.DetachedNode (DetachedNode, asTree', cutBranches, filterEmpty)
- import Web.DOM (Document, Node)
- import Web.DOM.Document as D
- import Web.DOM.Element as E
- import Web.DOM.Node (nodeName)
- import Web.DOM.NodeList as NL
- import Web.DOM.ParentNode (QuerySelector(..), querySelector, querySelectorAll)
- import Yoga.Tree (Tree)
- -- A light abstraction layer above the DOM manipulation API
- fromDocument ∷ Document → Node
- fromDocument doc = D.toNode doc
- queryOne :: String -> Document -> Effect (Maybe Node)
- queryOne selector doc = do
- found <- querySelector (QuerySelector selector) $ D.toParentNode doc
- pure case found of
- Nothing -> Nothing
- Just el -> Just $ E.toNode el
- queryAll :: String -> Document -> Effect (Maybe (NonEmptyList Node))
- queryAll selector doc = do
- found <- querySelectorAll (QuerySelector selector) $ D.toParentNode doc
- liftA1 NEL.fromFoldable $ NL.toArray found
- -- First pass of naming ; from here we know what we are looking for
- data LinkedInUIElementType = LinkedInUIArtDecoCard | LinkedInUIArtDecoTab | LinkedInUIJobsUnifiedTopCard
- instance Show LinkedInUIElementType where
- show LinkedInUIArtDecoCard = "ArtDecoCard"
- show LinkedInUIArtDecoTab = "ArtDecoTab"
- show LinkedInUIJobsUnifiedTopCard = "JobsUnifiedTopCard"
- data LinkedInUIElement = LinkedInUIElement LinkedInUIElementType Node
- instance Show LinkedInUIElement where
- show (LinkedInUIElement typ n) = "LinkedInUIElement(" <> show typ <> ", " <> nodeName n <> ")"
- getArtDecoCards ∷ Document → Effect (Maybe (NonEmptyList LinkedInUIElement))
- getArtDecoCards = queryAll' LinkedInUIArtDecoCard "section.artdeco-card > div ~ div > div > div > ul > li"
- getArtDecoTabs ∷ Document → Effect (Maybe (NonEmptyList LinkedInUIElement))
- getArtDecoTabs = queryAll' LinkedInUIArtDecoTab "div.artdeco-tabs > div > div > div > div > ul > li"
- getJobsUnifiedTopCard ∷ Document → Effect (Maybe (NonEmptyList LinkedInUIElement))
- getJobsUnifiedTopCard = queryAll' LinkedInUIJobsUnifiedTopCard "div.jobs-unified-top-card"
- queryAll' ∷ LinkedInUIElementType → String → Document → Effect (Maybe (NonEmptyList LinkedInUIElement))
- queryAll' constructor selector doc = do
- nodes <- queryAll selector doc
- pure case nodes of
- Nothing -> Nothing
- Just cards -> Just $ map (LinkedInUIElement constructor) cards
- asTree :: LinkedInUIElement -> Effect (Tree DetachedNode)
- asTree (LinkedInUIElement _ n) = asTree' n
- asPrunedTrees :: Maybe (NonEmptyList LinkedInUIElement) → Effect (Maybe (NonEmptyList (Tree DetachedNode)))
- asPrunedTrees =
- case _ of
- Nothing -> pure Nothing
- Just els -> do
- trees <- traverse asPrunedTree els
- pure $ Just $ trees
- asPrunedTree :: LinkedInUIElement → Effect (Tree DetachedNode)
- asPrunedTree el = do
- tree <- asTree el
- pure $ cutBranches filterEmpty tree
|