open-browser 0.2.1.1 → 0.3.0.0
raw patch · 17 files changed
+247/−143 lines, 17 filesdep ~Win32dep ~processsetup-changedPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: Win32, process
API changes (from Hackage documentation)
Files
- CHANGELOG.md +7/−0
- LICENSE +30/−30
- README.md +9/−9
- Setup.hs +2/−2
- example/Main.hs +5/−1
- lib/Web/Browser.hs +26/−19
- lib/Web/Browser/Linux.hs +0/−13
- lib/Web/Browser/OSX.hs +0/−13
- lib/Web/Browser/Windows.hs +0/−35
- lib/unix-like/common/Utils.hs +20/−0
- lib/unix-like/open/Web/Browser/OS.hs +17/−0
- lib/unix-like/xdg-open/Web/Browser/OS.hs +31/−0
- lib/unsupported-os/Web/Browser/OS.hs +13/−0
- lib/windows/Web/Browser/OS.hs +47/−0
- open-browser.cabal +35/−16
- stack.yaml +1/−1
- stack.yaml.lock +4/−4
CHANGELOG.md view
@@ -6,6 +6,13 @@ and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). +## 0.3.0.0 - 2025-03-16 + +* Make operating system-related choices at compilation. The function will never + succeed on unsupported operating systems, rather than than throwing an + `ErrorCall` exception. +* Drop support for 32-bit Windows. + ## 0.2.1.1 - 2025-03-15 * Add `CHANGELOG.md` and `README.md`.
LICENSE view
@@ -1,30 +1,30 @@-Copyright (c) 2015, rightfold - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of rightfold nor the names of other - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2015, rightfold++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of rightfold nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
README.md view
@@ -1,9 +1,9 @@-# open-browser - -A Haskell library that provides the function `openBrowser` that, given a URL, -yields an IO action that seeks to open the URL in the user's preferred web -browser. - -Supported operating systems are Windows, macOS, Linux and BSD. - -Originally developed by rightfold. +# open-browser++A Haskell library that provides the function `openBrowser` that, given a URL,+yields an IO action that seeks to open the URL in the user's preferred web+browser.++Supported operating systems are Windows, macOS, Linux and BSD.++Originally developed by rightfold.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple -main = defaultMain +import Distribution.Simple+main = defaultMain
example/Main.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE LambdaCase #-} + module Main ( main ) where @@ -5,4 +7,6 @@ import Web.Browser ( openBrowser ) main :: IO () -main = openBrowser "https://haskell.org/" >>= print +main = openBrowser "https://haskell.org/" >>= \case + True -> putStrLn "The operation succeeded!" + False -> putStrLn "The operation failed!"
lib/Web/Browser.hs view
@@ -1,30 +1,37 @@-{-# LANGUAGE CPP #-} +{-| +Module : Web.Browser +Description : Open a web browser from Haskell +Copyright : (c) rightfold 2015 +License : BSD3 +Maintainer : public@pilgrem.com +Open a web browser from Haskell. Supported operating systems are Windows, macOS, +Linux and BSD. +-} + module Web.Browser ( openBrowser ) where -#if defined(mingw32_HOST_OS) -import Web.Browser.Windows ( openBrowserWindows ) -#else -import Data.List ( isInfixOf ) -import System.Info ( os ) -import Web.Browser.Linux ( openBrowserLinux ) -import Web.Browser.OSX ( openBrowserOSX ) -#endif +import qualified Web.Browser.OS as OS -- | Seeks to open the given URL in the user's preferred web browser. Returns --- whether or not the operation succeeded. Throws an 'ErrorCall' exception if --- the operating system is unsupported. +-- whether or not the operation succeeded. No checks are performed on the +-- validity of the given URL. +-- +-- Implemented using: +-- +-- * on Windows, the \'open\' operation provided by the Win32 API; +-- +-- * on macOS, the \'open\' application, if it is on the user's PATH; and +-- +-- * on Linux, FreeBSD, OpenBSD or NetBSD, the \'xdg-open\' application, if it +-- is on the user's PATH, via \'sh\' to allow the application's output to be +-- silenced. +-- +-- On other operating systems, the operation always fails. openBrowser :: String -- ^ URL -> IO Bool -#if defined(mingw32_HOST_OS) -openBrowser = openBrowserWindows -#else -openBrowser - | any (`isInfixOf` os) ["linux", "bsd"] = openBrowserLinux - | "darwin" `isInfixOf` os = openBrowserOSX - | otherwise = error "unsupported platform" -#endif +openBrowser = OS.openBrowser
− lib/Web/Browser/Linux.hs
@@ -1,13 +0,0 @@-module Web.Browser.Linux - ( openBrowserLinux - ) where - -import System.Exit ( ExitCode (..) ) -import System.Process ( rawSystem ) - -openBrowserLinux :: String -> IO Bool -openBrowserLinux url = exitCodeToBool `fmap` rawSystem executable argv - where - (executable, argv) = ("sh", ["-c", "xdg-open \"$0\" 2>&1 > /dev/null", url]) - exitCodeToBool ExitSuccess = True - exitCodeToBool (ExitFailure _) = False
− lib/Web/Browser/OSX.hs
@@ -1,13 +0,0 @@-module Web.Browser.OSX - ( openBrowserOSX - ) where - -import System.Exit ( ExitCode (..) ) -import System.Process ( rawSystem ) - -openBrowserOSX :: String -> IO Bool -openBrowserOSX url = exitCodeToBool `fmap` rawSystem executable argv - where - (executable, argv) = ("open", [url]) - exitCodeToBool ExitSuccess = True - exitCodeToBool (ExitFailure _) = False
− lib/Web/Browser/Windows.hs
@@ -1,35 +0,0 @@-{-# LANGUAGE CPP #-} -{-# LANGUAGE ForeignFunctionInterface #-} - -module Web.Browser.Windows - ( openBrowserWindows - ) where - -import System.Win32.Types - ( HANDLE, HINSTANCE, INT, LPCTSTR, handleToWord, nullPtr, withTString ) - -openBrowserWindows :: String -> IO Bool -openBrowserWindows url = - withTString "open" $ \openStr -> - withTString url $ \urlStr -> - exitCodeToBool `fmap` c_ShellExecute nullPtr - openStr - urlStr - nullPtr - nullPtr - 1 - where - exitCodeToBool hinst - | handleToWord hinst > 32 = True - | otherwise = False - --- https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew -foreign import WINDOWS_CCONV unsafe "windows.h ShellExecuteW" - c_ShellExecute :: - HANDLE -- _In_opt_ - -> LPCTSTR -- _In_opt_ - -> LPCTSTR -- _In_ - -> LPCTSTR -- _In_opt_ - -> LPCTSTR -- _In_opt_ - -> INT -- _In_ - -> IO HINSTANCE
+ lib/unix-like/common/Utils.hs view
@@ -0,0 +1,20 @@+-------------------------------------------------------------------------------- +-- For operating systems that use an application on the PATH to open the URL. +-------------------------------------------------------------------------------- + +module Utils + ( openBrowserWith + ) where + +import System.Exit ( ExitCode (..) ) +import System.Process ( proc, waitForProcess, withCreateProcess ) + +openBrowserWith :: + String + -- ^ Name of relevant executable on the PATH. + -> [String] + -- ^ Arguments for executable. + -> IO Bool +openBrowserWith cmd args = + withCreateProcess (proc cmd args) $ \_ _ _ p -> + (== ExitSuccess) <$> waitForProcess p
+ lib/unix-like/open/Web/Browser/OS.hs view
@@ -0,0 +1,17 @@+-------------------------------------------------------------------------------- +-- For Unix-like operating systems, such as macOS, that provide the open +-- application on the PATH. +-------------------------------------------------------------------------------- + +module Web.Browser.OS + ( openBrowser + ) where + +import Utils ( openBrowserWith ) + +-- https://ss64.com/mac/open.html +openBrowser :: + String + -- ^ URL + -> IO Bool +openBrowser url = openBrowserWith "open" [url]
+ lib/unix-like/xdg-open/Web/Browser/OS.hs view
@@ -0,0 +1,31 @@+-------------------------------------------------------------------------------- +-- For Unix-like operating systems that provide the xdg-open application on the +-- PATH. +-------------------------------------------------------------------------------- + +module Web.Browser.OS + ( openBrowser + ) where + +import Utils ( openBrowserWith ) + +-- https://ss64.com/bash/xdg-open.html +openBrowser :: + String + -- ^ URL + -> IO Bool +openBrowser url = + -- sh -c '...' + -- + -- tells the shell (sh) to execute the given string as a command, and + -- the following argument (url) is passed as a positional argument $0. + -- + -- xdg-open "$0" 2>&1 > /dev/null + -- + -- The $0 is expanded and the double quotes ensures it is treated as a single + -- argument to xdg-open. + -- + -- 2>&1 redirects standard error to standard output. + -- + -- > /dev/null discards standard output. + openBrowserWith "sh" ["-c", "xdg-open \"$0\" 2>&1 > /dev/null", url]
+ lib/unsupported-os/Web/Browser/OS.hs view
@@ -0,0 +1,13 @@+-------------------------------------------------------------------------------- +-- For unsupported operating systems +-------------------------------------------------------------------------------- + +module Web.Browser.OS + ( openBrowser + ) where + +openBrowser :: + String + -- ^ URL + -> IO Bool +openBrowser = const (pure False) -- Operation never succeeds
+ lib/windows/Web/Browser/OS.hs view
@@ -0,0 +1,47 @@+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use camelCase" #-} + +{-# LANGUAGE ForeignFunctionInterface #-} + +-------------------------------------------------------------------------------- +-- For Windows operating systems, making use of the Win32 API. +-------------------------------------------------------------------------------- + +module Web.Browser.OS + ( openBrowser + ) where + +import System.Win32.Types + ( HANDLE, HINSTANCE, INT, LPCWSTR, handleToWord, nullPtr, withTString ) + +type HWND = HANDLE + +-- https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow +-- Activates and displays a window. If the window is minimized, maximized, or +-- arranged, the system restores it to its original size and position. An +-- application should specify this flag when displaying the window for the first +-- time. +sW_SHOWNORMAL :: INT +sW_SHOWNORMAL = 1 + +openBrowser :: + String + -- ^ URL + -> IO Bool +openBrowser url = + withTString "open" $ \openStr -> + withTString url $ \urlStr -> exitCodeToBool <$> + c_ShellExecute nullPtr openStr urlStr nullPtr nullPtr sW_SHOWNORMAL + where + exitCodeToBool hinst = handleToWord hinst > 32 + +-- https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutew +foreign import ccall unsafe "windows.h ShellExecuteW" + c_ShellExecute :: + HWND -- [in, optional] hwnd + -> LPCWSTR -- [in, optional] lpOperation + -> LPCWSTR -- [in] lpFile + -> LPCWSTR -- [in, optional] lpParameters + -> LPCWSTR -- [in, optional] lpDirectory + -> INT -- [in] nShowCmd + -> IO HINSTANCE
open-browser.cabal view
@@ -5,10 +5,9 @@ -- see: https://github.com/sol/hpack name: open-browser-version: 0.2.1.1-synopsis: Open a web browser from Haskell.-description: Open a web browser from Haskell. Currently BSD, Linux, OS X and Windows are- supported.+version: 0.3.0.0+synopsis: Open a web browser from Haskell+description: Open a web browser from Haskell. Windows, macOS, Linux and BSD are supported. category: Web homepage: https://github.com/mpilgrem/open-browser bug-reports: https://github.com/mpilgrem/open-browser/issues@@ -18,7 +17,7 @@ license-file: LICENSE build-type: Simple tested-with:- GHC >= 7.6+ GHC >= 8.4 extra-source-files: CHANGELOG.md README.md@@ -35,26 +34,46 @@ default: False library- exposed-modules:- Web.Browser- other-modules:- Web.Browser.Linux- Web.Browser.OSX hs-source-dirs: lib+ exposed-modules:+ Web.Browser build-depends: base ==4.*- , process ==1.*+ , process >=1.4.3.0 && <2 default-language: Haskell2010 if os(windows) other-modules:- Web.Browser.Windows+ Web.Browser.OS+ hs-source-dirs:+ lib/windows build-depends:- Win32- if arch(i386)- cpp-options: -DWINDOWS_CCONV=stdcall+ Win32 <3+ else+ if os(darwin)+ other-modules:+ Utils+ Web.Browser.OS+ hs-source-dirs:+ lib/unix-like/common+ lib/unix-like/open+ build-depends:+ process >=1.4.3.0 && <2 else- cpp-options: -DWINDOWS_CCONV=ccall+ if os(linux) || os(freebsd) || os(openbsd) || os(netbsd)+ other-modules:+ Utils+ Web.Browser.OS+ hs-source-dirs:+ lib/unix-like/common+ lib/unix-like/xdg-open+ build-depends:+ process >=1.4.3.0 && <2+ else+ other-modules:+ Web.Browser.OS+ hs-source-dirs:+ lib/unsupported-os executable open-browser-example main-is: Main.hs
stack.yaml view
@@ -1,1 +1,1 @@-snapshot: lts-23.10 # GHC 9.8.4 +snapshot: lts-23.14 # GHC 9.8.4
stack.yaml.lock view
@@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 889b6bffaf21cd509a7c6017703281e77c2f6df0a0908a11c85fa97fcbf11d4e - size: 680573 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/10.yaml - original: lts-23.10 + sha256: 1964d439d2a152be4238053f3f997a09fb348391984daab86d724975ef9a423f + size: 683814 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/14.yaml + original: lts-23.14