hbro-1.3.0.0: library/Hbro/Core.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Hbro.Core (
-- * Types
CaseSensitivity(..)
, Direction(..)
, Wrap(..)
, ZoomDirection(..)
-- * Getters
, getCurrentURI
, getFaviconURI
, getFavicon
, getLoadProgress
, getPageTitle
, getPageData
-- * Browsing
, goHome
, load
, reload
, reloadBypassCache
, stopLoading
, goBack
, goForward
-- * Other
, printPage
, searchText
, searchText_
, spawnHbro
, spawnHbro'
, quit
, saveWebPage
, executeJSFile
) where
-- {{{ Imports
import Graphics.UI.Gtk.WebKit.Lifted
import Graphics.UI.Gtk.WebKit.Lifted.WebView
import Hbro.Config as Config
import Hbro.Dyre
import Hbro.Error
-- import Hbro.Gui as Gui
import Hbro.Gui.MainView
import Hbro.Logger
import Hbro.Prelude as H
import Graphics.UI.Gtk.Gdk.Pixbuf (Pixbuf)
import Graphics.UI.Gtk.General.General.Extended
import Graphics.UI.Gtk.WebKit.WebDataSource
import Graphics.UI.Gtk.WebKit.WebFrame
import Network.URI.Extended
import System.Process.Extended
-- }}}
-- {{{ Types
data CaseSensitivity = CaseSensitive | CaseInsensitive
instance ToBool CaseSensitivity where
toBool CaseSensitive = True
toBool CaseInsensitive = False
data Direction = Forward | Backward
instance ToBool Direction where
toBool Forward = True
toBool Backward = False
data Wrap = Wrap | NoWrap
instance ToBool Wrap where
toBool Wrap = True
toBool NoWrap = False
data ZoomDirection = In | Out
-- }}}
-- {{{ Getters
getCurrentURI :: (MonadIO m, MonadReader r m, Has MainView r, MonadError Text m) => m URI
getCurrentURI = webViewGetUri =<< getWebView
getFaviconURI :: (MonadIO m, MonadReader r m, Has MainView r, MonadError Text m) => m URI
getFaviconURI = webViewGetIconUri =<< getWebView
getFavicon :: (MonadIO m, MonadReader r m, Has MainView r, MonadError Text m) => Int -> Int -> m Pixbuf
getFavicon w h = (\v -> webViewTryGetFaviconPixbuf v w h) =<< getWebView
getLoadProgress :: (MonadIO m, MonadReader r m, Has MainView r) => m Double
getLoadProgress = gSync . webViewGetProgress =<< getWebView
getPageTitle :: (MonadIO m, MonadReader r m, Has MainView r, MonadError Text m) => m Text
getPageTitle = webViewGetTitle =<< getWebView
-- | Return the HTML code of the current webpage.
getPageData :: (MonadIO m, MonadReader r m, Has MainView r, MonadError Text m) => m ByteString
getPageData = dataSourceGetData =<< io . webFrameGetDataSource =<< io . webViewGetMainFrame =<< getWebView
-- }}}
-- {{{ Browsing
goHome :: (MonadIO m, MonadLogger m, MonadReader r m, Has MainView r, Has (TVar Config) r, MonadError Text m) => m ()
goHome = load =<< Config.get homePageL
load :: (MonadIO m, MonadLogger m, MonadReader r m, Has MainView r, MonadError Text m) => URI -> m ()
load uri = do
debug $ "Loading URI: " ++ tshow uri
-- void . logErrors $ do
-- currentURI <- getURI
-- guard (currentURI /= uri')
-- Browser.advance currentURI
-- load' uri'
webview <- getWebView
gSync . webViewLoadUri webview $ show uri'
where
uri' = case uriScheme uri of
[] -> uri { uriScheme = "http://" }
_ -> uri
-- baseOf uri = uri {
-- uriPath = (++ "/") . join "/" . Prelude.init . split "/" $ uriPath uri
-- }
-- load' :: (MonadBaseControl IO m, MonadReader GUI m, HasHTTPClient t, MonadError Text m) => URI -> m ()
-- load' uri = do
-- page <- Client.retrieve uri
-- -- render page =<< Client.getURI
-- render page uri
reload, goBack, goForward :: (MonadIO m, MonadReader r m, Has MainView r, MonadLogger m) => m ()
-- reload = load =<< Client.getURI
-- goBack = load' =<< Browser.stepBackward =<< getURI
-- goForward = load' =<< Browser.stepForward =<< getURI
reload = gAsync . webViewReload =<< getWebView
goBack = do
gAsync . webViewGoBack =<< getWebView
unlessM (gSync . webViewCanGoBack =<< getWebView) $ warning "Unable to go back."
goForward = do
gAsync . webViewGoForward =<< getWebView
unlessM (gSync . webViewCanGoForward =<< getWebView) $ warning "Unable to go forward."
reloadBypassCache, stopLoading :: (MonadIO m, MonadLogger m, MonadReader r m, Has MainView r) => m ()
reloadBypassCache = getWebView >>= gAsync . webViewReloadBypassCache >> debug "Reloading without cache."
stopLoading = getWebView >>= gAsync . webViewStopLoading >> debug "Stopped loading"
-- }}}
-- {{{
searchText :: (MonadIO m, MonadLogger m, MonadReader r m, Has MainView r) => CaseSensitivity -> Direction -> Wrap -> Text -> m Bool
searchText s d w text = do
debug $ "Searching text: " ++ text
v <- getWebView
gSync $ webViewSearchText v text (toBool s) (toBool d) (toBool w)
searchText_ :: (MonadIO m, Functor m, MonadLogger m, MonadReader r m, Has MainView r) => CaseSensitivity -> Direction -> Wrap -> Text -> m ()
searchText_ s d w text = void $ searchText s d w text
printPage :: (MonadIO m, MonadReader r m, Has MainView r) => m ()
printPage = gAsync . webFramePrint =<< gSync . webViewGetMainFrame =<< getWebView
-- }}}
-- | Spawn another browser instance.
spawnHbro :: (MonadIO m, MonadLogger m) => m ()
spawnHbro = do
executable <- getHbroExecutable
spawn (fpToText executable) []
-- | Spawn another browser instance and load the given URI at start-up.
spawnHbro' :: (MonadIO m, MonadLogger m) => URI -> m ()
spawnHbro' uri = do
executable <- getHbroExecutable
spawn (fpToText executable) ["-u", tshow uri]
-- | Terminate the program.
quit :: (MonadIO m) => m ()
quit = gAsync mainQuit
-- {{{ Misc
saveWebPage :: (ControlIO m, MonadLogger m, MonadReader r m, Has MainView r, MonadError Text m) => FilePath -> m ()
saveWebPage file = writeFileE' file =<< getPageData
-- | Execute a javascript file on current webpage.
executeJSFile :: (MonadIO m, MonadLogger m) => FilePath -> WebView -> m ()
executeJSFile filePath webView' = do
debug $ "Executing Javascript file: " ++ fpToText filePath
script <- readFile filePath
let script' = asText . unwords . map (++ "\n") . lines $ script
gAsync $ webViewExecuteScript webView' script'
-- }}}
-- | Save current web page to a file,
-- along with all its resources in a separated directory.
-- Doesn't work for now, because web_resource_get_data's binding is missing...
_savePage :: Text -> WebView -> IO ()
_savePage _path webView' = do
frame <- webViewGetMainFrame webView'
dataSource <- webFrameGetDataSource frame
_mainResource <- webDataSourceGetMainResource dataSource
_subResources <- webDataSourceGetSubresources dataSource
return ()