GithubHelp home page GithubHelp logo

heinrichapfelmus / threepenny-gui Goto Github PK

View Code? Open in Web Editor NEW
437.0 437.0 77.0 4.28 MB

GUI framework that uses the web browser as a display.

Home Page: https://heinrichapfelmus.github.io/threepenny-gui/

License: Other

Haskell 91.87% Shell 0.16% JavaScript 6.70% CSS 0.05% HTML 0.33% Nix 0.89%
gui haskell javascript

threepenny-gui's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

threepenny-gui's Issues

Have TPG set up log file automatically

When I run TPG, I get a warning as soon as I start it up that access and error logs will be written to std error. I have been unsuccessful in identifying the path where I need to put the log files to get TPG (Snap) to use them. I've tried a few, but each time I get the same notice when I start my program.

I think TPG should create these files if they don't exist so that logging never encounters this issue. Also nice would be allowing the user to configure the path used for the log files.

The `getElementsBy..` functions do not work with a custom HTML file

getElementsByClassName is giving me problems. When calling it, I get the following error:

user error (Pattern match failure in do expression at Graphics/UI/Threepenny/Core.hs:143:5-15)

To reproduce:

  • add to <body> in wwwroot/chat.html:

    <div class="test">  
    </div>
    
  • replace in setup src/Chat.hs:

    getBody window #+
    

    by

      first <- head <$> getElementsByClassName window "test"
      element first #+
    

Threepenny.Reactive and Reactive.Banana.Threepenny

I have noticed that work on integrated FRP has already stared in the embed-frp branch. I realize that I am probably jumping the gun by raising this issue now, given how very new that is, but anyway: do you plan to support reactive-banana-threepenny once 0.3.0.0 is released?

Context: I have just attempted to build my current project with the head of embed-frp, hoping that it would take little more than averting name clashes and replacing the Control.Event functions with the corresponding Threepenny.Reactive ones. Obviously that didn't work, as things like blur in Graphics.UI.Threepenny.Events now have quite different types.Of course, there is no urgency about it (just me being nosy and trying to build stuff off the development head!), but I would like to plan ahead in case there will be a need to, e.g. port my code (and any missing reactive-banana combinators it might need) to Threepenny.Reactive, or writing an alternative Control.Event able to bridge reactive-banana and threepenny 0.3.*.

Character encoding issues when compiling resources files into library

I get the following compilation failure when building both from the latest version on github and the latest hackage version:

src/Graphics/UI/Threepenny/Internal/Resources.hs:15:7:
    Exception when trying to run compile-time code:
      src/Graphics/UI/jquery.js: hGetContents: invalid argument (invalid byte sequence)
      Code: Language.Haskell.TH.Quote.quoteExp
              include "Graphics/UI/jquery.js"

Bytestring dependency

Hi,

threepenny-gui 0.4.1 requires "bytestring >=0.9.2 && <0.11", however Graphics / UI / Threepenny / Internal / Driver.hs uses "LBS.fromStrict" which has been introduced in bytestring-0.10.0.0.

On my system (GHC 7.4.1 + HP), "cabal install threepenny-gui" fails because of that.

Simple GUI interaction uses a lot of memory

This might be a problem with my particular usage. Every time I do anything with the GUI, I see the memory footprint of my program shoot up 100-400 KB. Every time I drag and drop. Every time I click on a tab. (These are pretty much the only things my GUI can do right now.)

Driver code hits recursion limit

In FNIStash, I use a lot of TPG code to set up the GUI. Because the driver code is written in a recursive fashion, a lot of recursion goes on. Couple these things together and you can fairly easily hit the recursion limit in JS and get "too much recursion" errors in the web console. At first this was being triggered by JSON.stringify in console_log calls, but after commenting those out it still can arise.

Note that I encountered the recursion limit in FF, which caused TPG to be entirely unresponsive. When I switched to Chrome, which has a much higher limit, the issue disappeared. (for now)

Layout combinators to simplify GUI layout

I would like to simplify the API for GUI layout.

Since our focus is on GUIs, I wonder if we should downplay the full HTML capability and instead provide a few combinators for aligning GUI elements. WxHaskell has a layout combinators like grid, row and column that make it very easy to align elements. For instance, the following screen layout

was created by the following code

do
    f           <- frame    [ text := "CRUD Example (Simple)" ]
    listBox     <- singleListBox f []
    createBtn   <- button f [ text := "Create" ]
    deleteBtn   <- button f [ text := "Delete" ]
    filterEntry <- entry  f [ ]

    firstname <- entry f [ ]
    lastname  <- entry f [ ]

    let dataItem = grid 10 10 [[label "First Name:", widget firstname]
                              ,[label "Last Name:" , widget lastname]]
    set f [layout := margin 10 $
            grid 10 5
                [[row 5 [label "Filter prefix:", widget filterEntry], glue]
                ,[minsize (sz 200 300) $ widget listBox, dataItem]
                ,[row 10 [widget createBtn, widget deleteBtn], glue]
                ]]

Even though the layout is fairly complex, it can be specified in just 18 lines of Haskell code, half of which are essentially just a list of widgets.

The thing is that HTML allows very rich and aesthetically appealing user interfaces, but the design tends to take a lot of time (also because HTML+CSS has an impoverished box model compared to, say, TeX). When writing a GUI application, I wager that programmers probably to prototype the functionality first and upgrade the design later. Hence, a couple combinators for quickly creating layouts might come in very handy.

What is your opinion of the combinators grid, row, column?


Concerning style, WxHaskell specifies attributes as

set x [ attr := value, attr2 := value ]

but I don't think that this is worth copying. I prefer the elegant Ji style that uses chains of # in a clever way.

However, I would like to reduce the number of variants of #, #+, #= and so on, and streamline this part of the API as well. Unfortunately, there are many possibilities for doing so, and I have a hard time making decisions without guidance from example GUI code.


@daniel-r-austin, I would would be very interested in a screenshot of the GUI program you mentioned. Also, did you create elements mostly with the Haskell code (new and so on), or did you specify the layout by writing a HTML page first? What about GUI elements that are created dynamically, like elements of, say, a shopping cart?

Layout combinators to simplify GUI layout. Take 2.

This is essentially a continuation of issue #24 .

The goal of Threepenny is to make GUI development easy, and this also includes the visual aspects of UI design. Unfortunately, HTML and CSS are terrible languages for specifying box layouts.

What we really want is a nice Haskell API that hides the complexities of CSS and offers a nice way to specify layout. The grid, column and row combinators are a good start, but they are currently implemented as CSS tables, which tend to behave unpredictable, especially when content size changes dynamically.

Fortunately, it appears that the CSS 3 offers a new feature, flexbox layout, which apperas to solve most of the layout woes. Flexboxes may be a good start for implementing proper layout combinators in Haskell.

Flexboxes only work in newer browsers, but we could bundle our own browser during deployment #52 .

Build fails with ghc 7.8

template-haskell < 2.9 is needed, but 2.8.x cannot be built on ghc 7.8.x.
aeson-0.6.x has the same problem (also see issue #77).

aeson-0.6.2.1 depends on template-haskell-2.8.0.0 which failed to install.
threepenny-gui-0.4.1.0 depends on template-haskell-2.8.0.0 which failed to install.

Templates? :-)

Would give an arm for templates, url routing and some nice nice tutorial!

XxxXXX>>>>>>> Please plz plz don't let this project die!!!!

Mirror local files via the web server

I'm currently experimenting with implementing a small application for annotating videos in threepenny-gui.

In HTML5, videos can be included with the video tag like this

<video id="presentation-video" controls>
  <source src="data/video.mov">
  <source src="data/video.ogv" type="video/ogg">
</video>

I would like users to load their local video files into the player. However, for security reasons, the browser refused to accept URIs of the form file:// in the src tag. This not only applies to videos, but images and audio as well. The only way to pass a local file to the browser window is to mirror it via the threepenny server first.


Hence, I propose to add two functions

type URI = String

loadFile :: FilePath -> IO URI
loadDirectory :: FilePath -> IO URI

that instruct the web server to serve a file or directory under an URI of its choosing. In the case of a video, I can now load a local file into the player with

remoteFilename <- loadFile localFilename
element videoSource # set (attr "src") remoteFilename

A nice side effect of these functions is that they make the tpStatic parameter of the server configuration obsolete. The directoy for static resources can now be loaded dynamically in the setup.

static <- loadDirectory "wwwroot"
addStyleSheet (static </> "buttons.css")

Strings containing Scandinavian characters display incorrectly

When using a Haskell string as a property value on some element, Scandinavian characters (probably others as well) display incorrectly. Using a custom HTML file with a <meta charset="utf-8"> doesn't affect the issue.

The following minimal example should create a button with the text åäö. However, it actually creates a button with the text 98¦:

import Graphics.UI.Threepenny
main = do
  startGUI defaultConfig $ \w -> do
    getBody w #+ [button # set text "åäö"]
    return ()

SVG tags not rendered

Getting started with threepenny-gui and SVG I ported the simple example code from, http://www.w3schools.com/svg/, to this threepenny-gui Haskell,

module W3Svg (main) where

import           Control.Monad               (void)
import qualified Graphics.UI.Threepenny      as UI
import           Graphics.UI.Threepenny.Core

main :: IO ()
main = startGUI defaultConfig setup

setup :: Window -> UI ()
setup w = void $ do
    return w # set title "W3 Schools Svg"

    caption <- UI.h1 # set text "My first SVG in Haskell"

    -- <svg width="100" height="100">
    context <- mkElement "svg" # set (strAttr "width") "100"
                               # set (strAttr "height") "100"
    -- <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
    circle <- mkElement "circle" # set (strAttr "cx") "50"
                                 # set (strAttr "cy") "50"
                                 # set (strAttr "r") "40"
                                 # set (strAttr "stroke") "green"
                                 # set (strAttr "stroke-width") "4"
                                 # set (strAttr "fill") "yellow"

    getBody w #+ [element caption, element context #+ [element circle]]


-- Copied from Graphics.UI.Threepenny.Attributes
strAttr :: String -> WriteAttr Element String
strAttr name = mkWriteAttr (set' (attr name))   

However, when pointing a browser to http://localhost:8023 I see only the caption output and not the green and yellow circle of the example. Checking with the DOM inspector the tags seem to present, complete, and in the correct order.

Using newEventsNamed

On noticing newEventsNamed, my first thought was "here is a drop-in replacement for Control.Event.newEventsTagged". The second thought, of course, was "but how do I fire the events"? Eventually, I understood that newEventsNamedshould be the way it is; partly by finding its uses in the rest of Threepenny, and partly from trying to make it equivalent to the old newEventsTagged only to realize it is not as simple as it seems. On the other hand, it is easy to implement newEventsTagged using only the exported functions of Reactive.Threepenny, and it works perfectly well (I use it to create event-based getters without having to expose the corresponding Behavior). Given all of that, I am left with two questions: Is that a sensible use of newEventsNamed? And do you see a place for something in the vein of newEventsTagged in the API?

Problems with session clean up?

Let's keep this going! I noticed an issue the other day and I am not sure how to diagnose it. My TP worker starts out doing an IO action to read in a data file and build some Maps. After this is complete and I'm ready to start using my GUI, my program uses around 110-120 MB of memory. If I hit refresh in my browser, the memory in use goes to around 240-250 MB. The increase in memory make sense to me - the map is being rebuilt just like the first time. However, I don't understand why the old session's memory isn't cleaned up. I let my program idle for 20 minutes to be sure there is plenty of time for cleanup timers and whatnot to run, but the memory never goes down.

I threw in some trace calls to try to figure it out but have had no luck so far.

Executables in commit 9c92cc... fail to build

Tried to install threepenny-gui for the first time. The threepenny-examples-buttons failed to build because the json package is hidden. I added it to the exe's build-depends, but that led to the same issue with system.filepath. As a work around, I removed all the exe's from the cabal file and installed only the library (I believe successfully).

Screenshots for release

For the upcoming release, I would like to include links to and screenshots of applications developed with Threepenny.

@daniel-r-austin has a couple of screenshots on his projects' webpage http://fluffynukeit.com/?p=488, so I will just pick the most colorful one.

@duplode , could you post some visual fluff from your Stunts project?

Error when installing version 0.4.1.0

I'm trying to install threepenny-gui version 0.4.1.0 through cabal, but I'm getting the following error:

src\Graphics\UI\Threepenny\Internal\Driver.hs:251:24:
    Not in scope: `LBS.fromStrict'

Version 0.4.0.2 compiles fine.

Compile UI code to JavaScript

Hi,

Maybe a solution for too much traffic generated between server/client is to move the client code to the client (Haskell->JS) so the most of the client stuff that happen on client, stays on client.

Google’s GWT has something similar for Java and its solution might be used in 3p as well.

In GWT you're writing all the web-app code in Java, but the project is physically separated into 3 top directories/sections: server, client and shared.

  • server stuff is compiled into executable
  • client stuff is compiled into JS
  • server and client can use the code in shared

Client code is written in files that will be compiled into JS. That code has limitations on functions that can be used, but it is possible to use FFI for third-party JS functions and wrappers for JS vars.

Server code is full blown Haskell code that will be executed on host.

Not so much server/client communication.

Best regards,

vlatko

How to get the id attribute of an element?

I find that HTML attributes in Graphics.UI.Threepenny.Attributes module are all WriteAttr. I haven't found out how to get the id_ attribute (or any attribute) of an element?

BTW, is there a plan to support the data- attributes?

Rebrand docs and examples

The documentation and examples must be updated to be consistent with the new threepenny-gui branding.

Add a quit event/handler

TPG should offer users a way to register actions to be triggered when a user disconnects, navigates away from the page, closes the window, etc. Among other things, this would allow easy freeing of resources that were allocated for the user's session.

Hosting live examples

It would be cool if we could host the examples live, so that people can try them out without downloading anything.

FP Haskell Center offers to live hosting of Haskell code, but their terms of use are too vague for my taste.

At the moment, the application would have to be restarted every now and then, because event handlers of DOM elements are not garbage collected.

threepenny-gui StackOverflow tag

This is not really an issue, but arguably it qualifies as a meta-issue. I have just created a threepenny-gui tag in SO and added the handful of existing Threepenny questions to it. I used "threepenny-gui" rather than "threepenny" merely because that seems to be what askers are more likely to use. However, I just noticed there is a link in the Haskell Wiki page about Threepenny which leads to the new question interface in SO initialised with the (not yet existent) "threepenny" tag. That being so, you might want to take some of the following measures:

  • Changing the link in the Haskell Wiki to use the "threepenny-gui" tag.
  • Propose "threepenny" as a tag synonym for "threepenny-gui" and get enough tag users to approve it (there probably are not enough users right now, however).
  • Remove my "threepenny-gui" tag from the questions and replace it with the "threepenny" tag (or ask me to do it).

text-1.1 and aeson-0.7 support

Currently, text versions 1.0 and 1.1 are excluded by the version bounds. Could you release a new version with a relaxed upper bound on text?

Eliminate the TP monad and the MonadTP class

I would like to streamline the API by removing the TP monad and the MonadTP class.

The TP monad carries around some information about the session. However, the observation is that for functions like appendTo or getValue that operate on a particular element, the session information is essentially already encoded in the element argument. After all, the Element type can be thought of as pointing to one particular element in one particular browser window; so it's not just an "abstract" DOM node, but a specific instance in a particular session. To make a long story short, we can change the type to

getValue :: Element -> IO String

by tracking the session context with every Element.

This does not work for all functions. For instance, the getHead or getElementById functions need to refer to a particular session. However, I think it is natural to add an argument called Window which represents a particular browser window (and associated session context).

getElementById :: Window -> IO (Maybe Element)

I think that these two changes would improve the API syntactically while keeping it conceptually simple.

Please let me know what you think.

NixOS installation errors

When doing nix-env -i haskell-threepenny-gui-ghc7.6.3
the following errors are obtained: http://lpaste.net/105233.
This is probably due to the constraint on aeson version, which is ==0.6.*, while the nix packaged version is 0.7.0.3

Embed resources into executables that link to the library

To make installation of executables that use this library simple, the library should include all necessary resources, like the JS driver code or HTML pages, in the compiled executable and not refer to any outside directories.

This can be done using QuasiQuotation, but unfortunately, this triggers a bug in Haddock #12 , so I have disabled this feature for now.

Technological underpinnings: Websockets, Sunroof?

If I understand that correctly, calling a JS function from the serve side has a latency of ~500ms because the client side has to poll commands from the server. I don't mind a little latency, but with several function calls on the server side, this will become big very soon.

An implementation using websockets would alleviate this problem.

Then again, we may not want to reinvent the wheel and instead build everything on the recently released sunroof project, which is a full-blown JavaScript DSL in Haskell. It is very similar to the threepenny-gui approach, though with a slightly different emphasis.

A widget implementation experiment with Reactive.Threepenny

I have just finished a rewrite of the bounded input widget of Stunts Cartography with the explicit goal of making it conform to the three principles proposed by Apfelmus in this blog post. I am pleased with the result - it does everything I need, and both widget and application code are better than before. You can check the widget implementation and how the rest of the application uses it (look for the BI. import qualifiers). The rewrite was hugely instructive, and there are several interesting little points to be made; in order not to bore you with a(n even longer) wall of text, however, I will stick to the essentials for now, and wait for your comments:

  • Basic usage: new returns a widget with no model, which is then connected to the rest of the application with either plugModel or its convenience applications simpleModel and userModel. All of the these three functions return the model (i.e. a Behavior whose value is displayed and possibly modified through the widget and which follows whatever promises the widget specification makes - e.g., for BoundedInput, that the value will be constrained to the bounds specified through new). In my application, I had no need of using the more general plugModel, as I do not need to filter or otherwise process the raw user event before using it to define the model. If you want an example of it in action, the implementation of simpleModel should give the general idea.

  • Given the decoupling of model and widget in implementations like this one, I reckon that the best description of their relation is not "the widget has a model which is used by the application", but "the widget is a tool used by the application to define a model". In support of that point of view, I mention an analogy born out of a discarded experiment. Imagine that we modified new so that it incorporated plugModel in order to return both the Behavior and the widget in a tuple. It would then be used like this...

    (bFoo, widgetFoo) <- new ..
    

    ... which looks a lot like this:

    (eFoo, fireFoo) <- newEvent
    

    Just as newEvent produces an Event and an IO action to trigger it, the combination of new and plugModel produces a Behavior and a IO tool to display and modify it; that is, the widget.

  • It is almost spooky how this style seems to ensure that the only convenient way of doing things is the clean, DRY one. Once I bought into the model-widget decoupling idea, everything fell into its right place, and many design improvements suddenly became obvious. That applies not only to the BoundedInput itself but also to the application code which uses it - for one, it made me realize that Behaviors are vastly superior to Events with respect to defining the semantically relevant parts of the event network (as opposed to mere glue code).

(This issue is a follow-up of sorts to #40 and #49. It is related to, but distinct from and possibly complementary to, #53.)

Drawing on a canvas

Drawing is important for GUI applications and I propose that threepenny-gui offer some out-of-the-box facilities for that.

As a first step, I would be happy with a small number of drawing primitives that offer what the old Hugs Graphics Library or the newer gloss library can do.

Later on, we might ponder integration with the diagrams library.

Could not find module `Paths' during install

When I do cabal install threepenny-gui I get the following error:

....
In-place registering threepenny-gui-0.1.0.0...
Preprocessing executable 'threepenny-examples-bartab' for
threepenny-gui-0.1.0.0...

src/BarTab.hs:9:8:
    Could not find module `Paths'
    Use -v to see a list of the files searched for.
Failed to install threepenny-gui-0.1.0.0

I'm running Ubuntu with ghc version 7.6.2. cabal-install version 1.16.0.2 using version 1.16.0.3 of the Cabal library.

'checkedChange' commits missing after embed-frp merge

The commit 059aeee with the checkedChange event was not merged with develop along with the rest of the embed-frp branch. I would have sent a pull request adding it back, but I don't know if your preference is to merge or to rebase in such cases.

Change default port number 10000 ?

The default configuration for a Threepenny program is to listen on port 10000. However it turns out that µTorrent is listening on that port as well, which means that you can't use Threepenny applications while the µTorrent application is running.

This has caused at least one user to have installation woes with Threepenny, something which I wanted to avoid at all cost.

Any suggestions for a default port number that Threepenny should use instead?

Websockets don't work in Safari 5.1

The library no longer works in older versions of Safari, like 5.1. Apparently, this is due to changes in the websockets-0.8 library. The server logs the following message:

MalformedRequest (RequestHead {requestPath = "/websocket", requestHeaders = [("Sec-WebSocket-Key1","m669x[G8 1E i#h31rN04"),("Sec-WebSocket-Key2","^5l847(61z 5( 44!"),("Host","localhost:10000"),("Origin","http://localhost:10000"),("Connection","Upgrade"),("Upgrade","WebSocket")], requestSecure = False}) "Header missing: Sec-WebSocket-Key"

Issue reference in the dependency: jaspervdj/websockets#51 and jaspervdj/websockets#49 .

This is unlikely to be fixed, older browsers will probably not be supported.

Drag & Drop enhancements

We should probably put the drag & drop attributes and events into a single module.

We should also add an example that showcases all the available events and attributes.


Also think about drag data. Ideally, we want to put arbitrary Haskell values there, though that would probably require an FFI construction à la StablePointer. This discussion is probably best left to issue #23, though.

Conveniently loading JavaScript libraries

Hello again! It's been a while, but I finally got back to playing with Threepenny. My latest experiment involved bindings to a small subset of jQuery UI. While it works very well, the trickery involved was, ahem, interesting. Quoting one of my commit messages:

Experimenting with bindings to JQuery UI's Autocomplete widget.

The key complication arises from the fact that we need to have the library
fully loaded by the time we call autocompleteInit on the text box. As of
Threepenny 0.4.0.2, following usual JavaScript practice by chaining the
initialisation steps with callbacks is not feasible, at least as far as I can
see. Using the load event of the script element does not work either, as
JQuery (which handles element appendage behind the scenes) will evaluate the
script and eliminate the DOM element. The next best option, then, is to load
the script via a synchronous request. The JavaScript code for doing so was
wrapped with callFunction to keep it blocking.

It should be mentioned that the easiest way to load something like JQuery UI
would probably be through tpCustomHTML. That, however, would be rather
opaque and inflexible.

See also http://stackoverflow.com/a/2880147/2751851 , from which the sync
request snippet was mostly taken.

How sane do you think this approach is, and how long is it likely to survive given the evolution of the API? Also, I noticed that improvements to the FFI are being prepared for 0.5, including support for exporting Haskell callbacks. Will they be applicable to this scenario - for instance, by loading a library with jQuery's getScript while passing the rest of the Haskell initialization as a callback?

First class event handlers with AddHandler

I would like to make event handling more pleasant by making "the process of registering event handlers" first class.

The concept is probably best explained by referring to the source code of the Control.AddHandler module which I've introduced in commit fecc5c6 . The idea is to give a name to the "process of registering event handlers".

type Handler a = a -> IO ()
newtype AddHandler a = AddHandler { register :: Handler a -> IO (IO ()) }

In other words, events like button clicks or mouse movements are now represented by an AddHandler.

onClick     :: Element -> AddHandler ()
onMouseMove :: Element -> AddHandler MousePosition
onKey       :: Element -> AddHandler KeyWithModifiers

Besides being conceptually appealing, I think that this approach has two main advantages:

  1. It is now possible to transform the AddHandler themselves. For example, they are an instance of the Functor class, so that a mapping between event values a -> b induces a mapping AddHandler a -> AddHandler b, allowing us to obtain seemingly new events like onModifiers from old ones like onKey.
  2. It is only possible to add event handlers, but not to replace old ones. This is a subtle advantage, but it avoids a class of subtle bugs where you accidentally override an existing event handler. This also subtly works in favor of AddHandler being first-class.

Essentially, this is a baby version of FRP, but I think it makes a lot of sense in the imperative style. Of course, if more complicated transformations of events are desired (merging), then one should use a full-blown FRP library instead. Even then, the first-class event handling presented here provides a smooth transition.

Perhaps we should even go so far to call this thing Event instead of using the ugly name AddHandler.

What do you think?

Native shells and app deployment

While connecting to GUIs via a web browser is nice, it would also be great if we could package Threepenny apps as native applications.

Technology-wise, the idea is to write a native app ("shell") which contains the Threepenny application as resource. When run, the native app forks the Threepenny app, embeds a browser (say WebKit) and connects to the Threepenny server. Further more, the shell injects some JavaScript plugins into the web browser, which can be called from driver.js.

For instance, this would allow us to better deal with file system operations like opening and saving files, and we can use the system menu bar.

Ideally, the whole thing would be integrated with cabala, similar to the cabal-macosx package. I'm thinking of a package named threepenny-wrapper that hooks into cabal and which depends on threepenny-wrapper-wine and so on depending on the platform.

Such a system subsumes issue #27 where the question was about packaging resources with the library.

Reusable components with reactive-banana-threepenny

(I was unsure about to which repository I should post this. The code has actually more to do with reactive-banana than with Threepenny, but the case being made is mainly about Threepenny.)

I was wondering how convenient it would be to write reusable widgets for Threepenny. Nothing sophisticated would be needed at first, just the bare minimum so that we wouldn't have to rewrite or copy-paste stuff like a custom file picker on every project. So I went ahead and made a proof-of-concept, and now I am stunned at how easy it was, given that I basically started from scratch. It could be even simpler - someone wishing to use similar methods right now without any fanciness could just drop the trivial Component class.

I do not know how sound this approach to components would be in the long run, and interesting questions would arise were it to be made more general. For instance, how to minimize the boilerplate needed for defining the component data type? Or what the best way to let users style components is? (Just export the Element fields and let users do whatever they want with them? Or perhaps add styling hooks into the component network?) In any case, and however the actual code might look like, I believe it would be good if Threepenny users were made aware of the possibility of defining reusable widgets, be it through the packaged examples, or, eventually, even through novel support modules.

Add example to Haddock API documentation

Daniel Diaz suggests:

My only suggestion is that a little example should be included in the API documentation, maybe in the Graphics.UI.Threepenny module. The examples provided in the library are nice, but sometimes you look at the API first (as I do) and it might help. Personal opinion, of course.

Also, you may point to the Graphics.UI.Threepenny.Core module in the cabal description or the Graphics.UI.Threepenny module, since I think is the best place to start reading the API docs.

EDIT: You can also point to some information about how to use FRP with threepenny-gui!

Stylesheet files cached too long in Chrome

It appears that Chrome caches stylesheet files regardless of whether the server would return a newer one. This messes up the display when trying different examples (For example first Chat.hs, then BarTab.hs) or when developing an application.

I don't know how to fix this right now, but it probably involves setting sone sort of "no-cache" header in the HTTP response. This should be done not only for style files, but for all other files (JS, loadFile) as well. We assume that the server runs on localhost anyway.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.