M src/Main.hs => src/Main.hs +3 -1
@@ 111,7 111,9 @@ searchSession session = do
     method GET
     q <- look "q"
     session' <- liftIO $ readMVar session
-    let results = [(header, labelEmpty $ engine q session') | (header, engine) <- Q.engines]
+    results <- forM Q.engines $ \(header, engine) -> do
+        results' <- liftIO $ engine q session session'
+        return (header, labelEmpty results')
     Tpl.inspector ok (Txt.pack ('๐':q)) session' $ \langs -> H.main $ do
         H.aside $ do
             H.form $ do
 
M src/UI/Search.hs => src/UI/Search.hs +26 -9
@@ 6,25 6,42 @@ import Text.Blaze.Html5.Attributes as A
 import Text.Blaze.Html
 import Data.Text as Txt
 
+import Data.UUID as ID
+
 import Internal
 import Messages
 
 import Network.URI (parseAbsoluteURI)
+import qualified Internal.Elements as Els
+import qualified Text.XML.Cursor as XC
+
+import Control.Monad (mapM)
 
 engines :: [(
     [Text] -> Html,
-    String -> Session' -> [[Text] -> Html]
+    String -> Session -> Session' -> IO [[Text] -> Html]
   )]
 engines = [
-    (const "URL", offerToLoad)
-  ]
-
-offerToLoad q _ | Just _ <- parseAbsoluteURI q = [\langs -> do
-    result q q
-    H.form ! action "nav/load" ! method "POST" $ do
-        input ! type_ "hidden" ! name "url" ! value (stringValue q)
-        button ! type_ "submit" ! class_ "disclosure" ! A.title (l' langs DebugLink') $ disclosure
+    (const "URL", offerToLoad),
+    (const "CSS", queryEls "css selector")
   ]
 
 result href' label = a ! href (stringValue href') ! target "preview" $ string label
 disclosure = "โคท"
+
+---
+
+offerToLoad q _ _ | Just _ <- parseAbsoluteURI q = return [\langs -> do
+        result q q
+        H.form ! action "nav/load" ! method "POST" $ do
+            input ! type_ "hidden" ! name "url" ! value (stringValue q)
+            button ! type_ "submit" ! class_ "disclosure" ! A.title (l' langs DebugLink') $ disclosure
+      ]
+    | otherwise = return []
+
+queryEls method q session session'
+    | Right ret <- Els.find (Els.Find method q) $ XC.fromDocument $ document session' = do
+        Prelude.map formatEl <$> mapM (\el -> (,) el <$> registerEl session el) ret
+    | otherwise = return []
+
+formatEl (el, uuid) langs = result ("el/" ++ ID.toString uuid ++ "/preview") $ show $ XC.node el
 
M src/Webdriver.hs => src/Webdriver.hs +1 -1
@@ 56,7 56,7 @@ serveSession sessions = WD.withSession fail (\uuid session -> msum [
             dir "fullscreen" $ unsupportedOp
         ],
         dir "frame" $ msum [noSuchFrame, dir "parent" $ ok $ toResponse ()], -- Noops
-        dir "element" $ findFromRoot session
+        dir "elements" $ findFromRoot session
     ]) sessions
   where
     fail uuid'| Just _ <- ID.fromString uuid' = errJSON 404 "invalid session ID" $ (