Coder Social home page Coder Social logo

domina's Introduction

What is Domina?

Domina is a jQuery inspired DOM manipulation library for ClojureScript. It provides a functional, idiomatic Clojure interface to the DOM manipulation facilities provided by the Google Closure library.

Warning: Domina is still beta-level software. Everything should work, but there may still be bugs, browser incompatibility or performance issues. Please report them!

Pull requests are extremely welcome.

You can obtain Domina by pulling from Clojars: [domina "1.0.3"].

Rationale

Previously, there was no straightforward way to do DOM manipulation in ClojureScript. The Google Closure library is available, but it does not represent a fluid, functional approach to DOM manipulation that users of libraries such as jQuery are accustomed to. jQuery itself, as well as other DOM manipulation libraries, are not easy to use with ClojureScript due to incompatibilities with the advanced mode compiler.

However, a jQuery-esqe, functional approach to DOM manipulation is extremely well suited to ClojureScript. Domina, while it does not provide any innovations, attempts to provide a basic functional interface to DOM manipulation that feels natural in ClojureScript. For a good library that takes a novel, alternative approach to DOM manipulation inspired by Clojure's Enlive, consider Enfocus.

Key Concepts

Content

Most of Domina's functions accept or return content, an abstraction that represents one or more DOM nodes, rather than DOM nodes themselves. Content is implemented as a protocol (DomContent) which responds to two methods, nodes and single-node. nodes returns a sequence of DOM nodes, single-node returns a single DOM node (usually the first one), if the content contains multiple nodes.

Entities which implement DomContent include:

  • Individual nodes
  • Sequences of nodes
  • Built-in HTML node collections such as NodeList
  • Strings (which are parsed into one or more nodes)
  • Selectors (such as xpath) create reified DomContent objects directly

Selectors

Selector functions take a string and return a DomContent representing matching nodes. For example, the xpath function in the domina.xpath namespace:

(xpath "//div[@class='foo']/p[2]")

This expression returns a content containing all the paragraph elements in a document which are the second children of divs with an class of 'foo'.

The xpath function also takes an optional first argument (which can be any DomContent) representing the context node(s) from which XPath evaluation will start. This allows selectors to be chained:

(-> (xpath "//body")
    (xpath "div")
    (xpath "p")
    (xpath "span"))

The sel function in the domina.css namespace works the same way for CSS selectors:

(sel ".my-class")
(sel "#my-id")
(-> (sel "body")
    (sel "div")
    (sel "p")
    (sel "span"))
(sel "body > div > p > span")

Other selector functions include the core functions by-id and by-class which return a DomContent based on node id and node class, respectively.

Examples

Append a <div> to the body element:

(append! (xpath "//body") "<div>Hello world!</div>")

Move a <div> from the end of the document to the beginning:

(prepend! (xpath "//body") 
         (detach! (xpath "//body/div[last()]")))

Add a CSS class on a node with a particular id:

(add-class! (by-id "foobar") "baz")

Delete all nodes of a given class:

(destroy! (by-class "foo"))

Set some colors on all child nodes of <div> elements with a class of 'foo':

(set-styles! (xpath "//div[@class='foo']/*")
            {:background-color "black"
             :color "white"})

Set the text content of a node:

(set-text! (by-id "foobar") "Lorem ipsum...")

Get the values of all <input> elements on the page:

(map value (nodes (xpath "//input")))

For examples of every currently implemented function, see the test.cljs file in the code repository, which exercises each function in unit tests against a DOM page.

Event Handling

Domina contains a robust event handling API that wraps the Google Closure event handling code, while exposing it in a idiomatic functional way.

Event Propagation

In Domina, every event has a target. This is the DOM node that is logically "causing" the event. All events triggered by the browser (such as clicks or key presses) are associated with a node. User defined events must also specify a target node.

Event listeners are also attached to nodes, and may trigger on either the capture or bubble phases of event propegation. The capture phase starts at the root node of the document, and successively fires any listeners on ancestors of the target node from the top down, down to the event target itself. In the bubble phase, the process is reversed, first firing listeners on the target node, then on each of its ancestors in succession back to the document root.

Registering Event Listeners

Use the listen! function to register an event handler in the bubble phase, and capture! to register a handle for the capture phase. Both take similar argument: a Domina DomContent, the event type, and a listener function. They return a sequence of event handler keys (see section below on de-registering event handlers)

(listen! (sel "button") :click (fn [evt] (log "button clicked!")))

This above snippet adds an event handler to every <button> element on the page, which logs a message when the button is clicked.

Note that the content argument is optional: in this case, the listener is added to the root node of the document, and will catch all click events on the entire page.

(listen! :click (fn [evt] (log "button clicked!")))

Event Objects

When an event is triggered, it invokes the provided listener function, passing it an event object. The event object will implement ClojureScript's ILookup protocol, as well as the domina.events.Event protocol.

Implementing the ILookup protocol makes it easy to pull values from browser events using ClojureScript's built in lookup functions such as get and contains?, as well as using keywords in function position. Note that although native events only have string keys, Domina will attempt to translate keywords to strings for lookup purposes.

(defn sample-click-handler [evt]
   (let [x (:clientX evt)
          y (:clientY evt)]
       (log (str "Click occurred at window coordinates " x "," y))))

The domina.events.Event protocol supports the following methods:

  • prevent-default Prevents the default action for an event from firing. For example, if you invoke prevent-default on a click event on a link, it will prevent the browser from navigating the browser as it normally would with a clicked link.
  • stop-propagation Prevents all future event listeners (in both the bubble and capture phases) from recieving the event.
  • target Returns the target node of the event.
  • current-target Returns the current target of the event (the node to which the current listener was attached).
  • event-type Returns the type of the event.
  • raw-event Returns the underlying goog.events.Event object, rather than it's Domina wrapper.

De-registering Event Handlers

There are several ways to de-register an event handler.

If you have the key returned by the registration function, you can de-register the handler by calling the unlisten-by-key! function, passing it the key as a single argument.

If you do not have the key in hand, you can remove all listeners from a node (or set of nodes) using the unlisten! function. It takes a DomContent, and an optional event type. If the event type is specified, it will only de-register handlers for that type, otherwise it will de-register everything from the specified node.

(unlisten! (sel "button") :click)  ; removes all click event handlers from all button elements
(unlisten! (sel "button"))  ; removes all event handlers of any type  from all button elements

There are also listen-once! and capture-once! variants of listen! and capture! which de-register themselves after the first time they are triggered.

Custom Events

In addition to native events dispatched by the browser, Domina allows you to create and dispatch arbitary events using the dispatch! function.

The dispatch! function takes an event target as a DomContent (assumed to be a single node), an event type, and an event map. Keys and values in the event map are merged in to the event object, and can be used to pass arbitrary data to event handlers.

(dispatch! (by-id "evt-target") :my-event {:some-key "some value"})

The event will be propegated through the capture and bubble phases just like a browser event, and can be caught in the normal way:

(listen! (by-id "evt-target") :my-event (fn [evt] (log (:some-key evt))))

Note that if you omit the event target when calling dispatch! (or when registering a listener), it will default to the root node of the document. This is often desirable when using custom application-wide events that have no logical mapping to any particular location in the DOM tree.

Important note on browser XPath compatibility (IE and Android).

Internet Explorer does not support DOM Level 3 XPath selectors. In order to utilize the domina.xpath namespace, you will need to include a pure-javascript XPath DOM Level 3 implementation.

A fast implementation known to work is provided by Cybozu Labs at http://coderepos.org/share/wiki/JavaScript-XPath. It is ignored on all browssers which already have native XPath support.

To include it on your page, enter the following line in your head element, before you reference any ClojureScript scripts.

    <script type="text/javascript" src="cybozu-xpath.js"></script>

Android

The situation with the Android browser (version 2.x, it is fixed in version 3) is even worse. The browser does not support XPath, but erroneously reports that it does. To make Domina's XPath support work on an Android device, you must include the following code snippet on your HTML page before including the cybozu-xpath.js file:

    <script type="text/javascript">
      /* Android 2.x claims XPath support, but has none.  Force non-native
         XPath implementation in this case */
      if (document.implementation
           && document.implementation.hasFeature
           && document.implementation.hasFeature("XPath",null)
           && !document.evaluate) {
        window.jsxpath = {
          targetFrame: undefined,
          exportInstaller: false,
          useNative: false, /* force non-native implementation */
          useInnerText: true
        };
      }
    </script>
    <script type="text/javascript" src="xpath.js"></script>

This script checks that if the browser claims XPath support, if it actually has it (via the presence of the document.evaluatefunction) and if not, sets a flag that tells Cybozu's XPath implementation to override native support.

If you're using a different XPath implementation, you'll need to use whatever means it provides to override native XPath handling.

We decided not to compile this functionality directly into Domina for two reasons:

  • Potential licensing issues
  • Reduced code size. With some server side conditions, it is possible to avoid downloading the script altogether for browsers which support XPath natively, which is obviously not possible to determine at compile-time.

Running the Tests

To execute the test suite ...

  1. Run lein cljsbuild test. This will generate a suite of test HTML files in the public directory (e.g., test_no_opt.html, test_advanced.html, etc.). Each file runs test.cljs in the context of the DOM, and each file represents a different compiler optimization setting.
  2. Open each of the public/test_*.html files in a browser and verify that all the tests pass.

Todo

See the projects Trello page

If you'd like to participate, please just let me know and I'll add you.

License

Copyright © 2012 Luke VanderHart

Distributed under the Eclipse Public License, the same as Clojure.

domina's People

Contributors

aeosynth avatar alandipert avatar bobby avatar ckirkendall avatar fogus avatar jasonrudolph avatar jsyrjala avatar levand avatar magomimmo avatar nbeloglazov avatar sgrove avatar sherbondy avatar stuarth avatar trptcolin avatar

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  avatar  avatar  avatar

domina's Issues

Problem with clojurescript jar from Maven

I was having a problem with leiningen trying to resolve a dependency for org.clojure/clojurescript 0.0-1069 which couldn't be found, changing this to version 0.0-1011 in the pom file seemed to solve that issue. I know someone on google groups was having this issue as well.

Move to a multi segment namespace

When compiling a ClojureScript project I get this warning

WARNING: domina is a single segment namespace at line 1 file:/Users/user/.m2/repository/domina/domina/1.0.3/domina-1.0.3.jar!/domina.cljs

It would probably be better to move to a multi segment namespace, single segment namespaces are generally avoided

domina/nodes always returns an empty collection in :optimizations :simple

domina/nodes always returns an empty collection in :optimizations :simple, but works as expected in optimizations :advanced

To see the issue, for some page with a few divs, run the following code

(js/alert (domina.css/sel "div"))
(js/alert (domina/nodes (domina.css/sel "div")))

The first line
works fine in both :optimizations :simple and :optimizations :advanced

The second line
With :optimizations :simple, an empty collection is displayed
With :optimizations :advanced, a collection of htmlelements is displayed

[domina "1.0.2"]
[org.clojure/clojurescript "0.0-2234"]
[lein-cljsbuild "1.0.3"]

Discuss XPath on Android

I thought it might be worth mentioning Android support in the documentation.

Android 2.x (which has a 95% share on Android devices), doesn't implement XPath, but it erroneously claims that it does via the document.implementation.hasFeature mechanism. This causes xpath.js to refuse to install.

Android doesn't have document.evaluate. By detecting this, and setting the useNative: false config option, prior to loading xpath.js, android will use the xpath.js implementation and work fine.

    <script type="text/javascript">
      /* Android 2.x claims XPath support, but has none.  Force non-native
         XPath implementation in this case */
      if (document.implementation
           && document.implementation.hasFeature
           && document.implementation.hasFeature("XPath",null)
           && !document.evaluate) {
        window.jsxpath = {
          targetFrame: undefined,
          exportInstaller: false,
          useNative: false, /* force non-native implementation */
          useInnerText: true
        };
      }
    </script>
    <!-- Non-native XPath implementation for IE and Android 2.x -->
    <script type="text/javascript" src="js/xpath.js"></script>

So, three things are currently an issue in preventing Android 2.x from working:

  1. Android doesn't natively support xpath.js
  2. xpath.js isn't loaded on Android, due to the conditional comment
  3. Android lies about its non-existent xpath support, causing xpath.js to not install, unless useNative is explicitly overridden

It should be possible to listen on a node that also happens to have child nodes.

I spent a few hours today tracking down this issue, so thought I'd write it up as a gotcha.

I was trying to listen to submit events on a form.

<form id="myform">
  <input type="text"></input>
  <input type="submit"></input>
</form>

This was my first attempt.

(events/listen!
   (by-id "myform") "submit"
   (fn [ev] (.log js/console "Submit")))

It doesn't work.

But this works :-

<button id="test"/>

(events/listen!
   (by-id "test") "click"
   (fn [ev] (.log js/console "OK")))

And, going back to the previous example, this works too :-

(events/listen!
   (domina.css/sel "#myform") "submit"
   (fn [ev] (.log js/console "Submit")))

So does this.

(events/listen!
   [(by-id "myform")] "submit"
   (fn [ev] (.log js/console "Submit")))

Notice that I've wrapped the node in a vector.

But this doesn't :-

(events/listen!
   (by-id "myform") "submit"
   (fn [ev] (.log js/console "Submit")))

And I think it should.

Why doesn't it work?

If we look at the events/listen! function we see it is wrapper the node with domina/nodes. That's what you want if you're passing a NodeList (perhaps found using a selector). But in the case of an HTML form, it returns the 2 child nodes (the input text and submit button).

So

(events/listen!
   (by-id "myform") "submit"
   (fn [ev] (.log js/console "Submit")))

adds the event listener to both inputs, but not to the form.

I think the DomContent protocol is complects the notion of parenthood with the notion of a collection of nodes. They are not the same thing.

events/listen! does not work with :optimizations :advanced (??)

This seems weird enough that I assume the problem lies in my code, but I don't see what I'm doing wrong...

My code works correctly until I compile it with :optimizations :advanced. Then, the domina event listener seems to return a raw object, rather than the DOM node I expected:

(defn dbg1 [x]
  (log "1: " (by-id "tabbar"))
  (log "2: " x))

(defn ^:export init []
  (events/listen! (by-id "tabbar") :click #(dbg1 %)))

I click on the page, and the console shows:

1: [object HTMLDivElement]
2: [object Object]

Implement CSS selectors

Determine how to write a function that takes a CSS selector string and returns a DomContent. I'd like to avoid pulling in Dojo as a third party dependency, but it might be the only cross-browser way. Investigate this.

Events don't behave correctly

The following does not work in any browser I tested.

(listen! :click (fn [evt] (log "button clicked!")))

Nor does

(listen! js/document :click (fn [evt] (log "button clicked!")))

String as DomContent doesn't work for table-related elements

Expected:

(.log js/console (single-node "<tr><td>Foo</td></tr>"))

to print to the console:

<tr><td>Foo</td></tr>

i.e. a Table Row Element

Actual

(.log js/console (single-node "<tr><td>Foo</td></tr>"))

printed to the console:

Foo

i.e. a Text Node Element

This discrepancy is due to a known bug in goog.dom.htmlToDocumentFragment: http://code.google.com/p/closure-library/issues/detail?id=210. The TR and TD (as well as TH, THEAD, TBODY, TFOOT) tags are stripped out when converting from a string to DOM elements, leaving only concatenated text nodes.

This issue impacts a use case that I think is quite common -- A string containing a table row is used as a template for each element of a collection, it is manipulated and inserted into the DOM.

Namespace issue?

I have included domina in my project.clj as follows:

[domina "1.0.0-alpha2"]

At a cljs repl I can do:

(load-namespace 'domina)

which produces:

WARNING: satisfies? already refers to: #'clojure.core/satisfies? in namespace: domina.macros, being replaced by: #'domina.macros/satisfies?

So far so good. But:

(domina/by-id "fun")

Gives me:

"Error evaluating:" (domina/by-id "fun") :as "domina.by_id.call(null,"fun");\n"

<TypeError: domina.by_id is undefined>

Oddly enough:

(load-namespace 'domina.xpath)
(domina.xpath.xpath "//body/p[@Class='fun']")

gives:

<[object Object]>

Also if I do:

(load-file "domina.cljs")
(domina/by-id "fun")

I get:

<[object HTMLHeadingElement]>

Any ideas what could could be causing this? I thought it might be a class path issue, but since I can reack domina.js using load-file, this does not appear to be the case.

domina 1.0.1 jar duplicate files

Here's something odd I noticed about the domina 1.0.1 jar on clojars. The tree structure of the extracted jar looks like this:

.
├── cljs
│   ├── domina
│   │   ├── css.cljs
│   │   ├── events.cljs
│   │   ├── macros.clj
│   │   ├── support.cljs
│   │   └── xpath.cljs
│   └── domina.cljs
├── domina
│   ├── css.cljs
│   ├── events.cljs
│   ├── macros.clj
│   ├── support.cljs
│   └── xpath.cljs
├── #domina.cljs#
├── domina.cljs
├── META-INF
│   ├── leiningen
│   │   └── domina
│   │   └── domina
│   │   └── project.clj
│   ├── MANIFEST.MF
│   └── maven
│   └── domina
│   └── domina
│   ├── pom.properties
│   └── pom.xml
└── project.clj

As you can see, all clojurescript files in the domina/ folder are duplicated in the cljs/ folder. Is there a reason for this duplication?

Unable to dispatch a click event

Hi,

I am trying to dispatch a click event on a button -

(defn enter-to-click
  "It captures the enter event on the given element selector (s1) and triggers a click event on the element selector (s2)"
  [s1 s2]
  (let [el1 (sel s1) el2 (sel s2)]
    (listen! el1 :keydown (fn [ev]
                            (when (= (:keyCode ev) 13)
                              (dispatch! (sel "#sign_in") "click" {}))))))

The listen! event works, I am even able to log messages from the when block , however the dispatch doesnt work. I am however able to trigger a click event using jquery from the browsers console.

Any help will be appreciated.

Thanks,
Murtaza

Need to remove a 'y' in the readme.

In the documentation there's just a typo, I believe—

"De-registering Event Handlers

There are several ways to de-register an event handler.

If you have they key returned"

should read

"De-registering Event Handlers

There are several ways to de-register an event handler.

If you have the key returned"

so basically just removing a y

get-data/set-data! don't seem to work with "normal" data attributes

I'm not really sure how to structure this issue, but basically I'm curious about the thinking behind get-data and set-data!. It seems that, rather than returning/modifying data attributes, they modify a custom "__domina_data" attribute. If one expects to be able to do something like retrieve or add/update an HTML data attribute, they don't work.

Can you give a use-case for get-data/set-data! ?

touch event information

Just finished a long hack session getting touch events to work. Turns out google helpfully strips out the touch information from touch events before domina gets them, and then the touch events don't really support any of the stuff documented here:

https://developer.mozilla.org/en-US/docs/DOM/TouchEvent

My solution is here - basically getting the original browser event and accessing its touch stuff.

http://stackoverflow.com/questions/15732028/clojurescript-touch-events-and-domina/15745781#15745781

It would be nice if domina could make up for google's shortcoming by making the touch information available in the domina event structures.

Including Domina 1.0.0 in project.clj blocks some closure library access

Thank you for this great library. I use it extensively. The problem I am having boils down to this:

Using Leinengen 2.0 and a project.clj with dependencies:

             [[org.clojure/clojure "1.5.0"]
             [org.clojure/clojurescript "0.0-1586"]
             [domina "1.0.0"]
             [org.clojure/google-closure-library-third-party "0.0-2029"]]

From the prompt provided by "lein trampoline cljsbuild repl-rhino" and the namespace created with "(ns testing (:require [goog.db :as db]))" the command "(type goog.db.openDatabase)" returns an "undefined" error, apparently in reference to the goog.db namespace.

But when I remove the domina dependency from the above project.clj, the same series of commands properly finds and evaluates the goog.db reference.

Bug in 'array-like?' that messes up selection of 'form' elements.

If a form element does not contain 'name' attribute domina has trouble selecting it because array-like? returns '0' instead of false. It looks like you have detected the same issue with select boxes and that is why you added the -name check. Maybe it would be better to check these types of nodes in some other way. Maybe a hash list of node-types with these properties.

(defn- array-like?
  [obj]
  (and obj ;; is not nil
       (not (.-name obj)) ;; is not an element (i.e, <select>)
       (.-length obj))) ;; has a length

Creighton

License?

Hey Luke, would you mind tacking a license on this bad boy? Thanks! -Alan

Is there a way to avoid side effects when parsing html strings?

I am trying to use domina to extract information from html received from another website (which I don't control, and which doesn't have a proper API). The basic issue is this:

If I do:

(html-to-dom "<img src=\"foo.jpg\">")

the browser will do a request to whatver.url/foo.jpg. The same applies to nodes and single-node, of course. Is there a way around that, or should I use a different library? I know enlive uses its own, more abstract representation of nodes, which is also nice for examining and doing arbitrary stuff on them, but I would be happy with just avoiding the side effects.

Cross-browser testing

  • Develop a matrix of all targeted browsers and OSes
  • Run the test page on each one to make sure it works
    • If there are problems, fix them.
  • Investigate feasibility of automating this process for easy regression testing across all browsers.

Clone already referenced & No XPathResult namespace

I just started testing Domina, and as soon as I compile it using lein cljsbuild once I am getting the following warnings:

Compiling "resources/public/test.js" from ["src/cljs"]...
WARNING: clone already refers to: /clone being replaced by: domina/clone at line
 147 file:/C:/Users/Proprietaire/.m2/repository/domina/domina/1.0.2/domina-1.0.2
.jar!/domina.cljs
WARNING: No such namespace: XPathResult at line 30 file:/C:/Users/Proprietaire/.
m2/repository/domina/domina/1.0.2/domina-1.0.2.jar!/domina/xpath.cljs
WARNING: No such namespace: XPathResult at line 41 file:/C:/Users/Proprietaire/.
m2/repository/domina/domina/1.0.2/domina-1.0.2.jar!/domina/xpath.cljs

The XPathResult warning appears when I include xpath: [domina.xpath :only [xpath]]

I use the latest ClojureScript. I did some reasearch and I haven't found anything regarding this issue, so I am wondering if it is my setup that is wrong or an actual issue with Domina.

Do not restrict listen! to 'builtin-types'

Currently, keywords passed to listen! & co are restricted to builtin-types, which is a set constructed from goog.events.EventType. Unfortunately, this approach doesn't allow to use keywords for subscribing to events, dispatched by goog.ui.Component subclasses, for example goog.ui.TabBar:

(listen! :active tabbar #(...))
;;       ^^^ this won't work

What are the options here? I think domina could:

  • either convert all keyword arguments to strings and don't do any validation;
  • extend builtin-types with keys from all possible EventType enums or provide a way for a user to do it.

Key Codes not working properly on key events

Consider the following code:

(listen! (sel "body") :keypress (fn [evt] (println "Keypress" (:keyCode evt)))) 

On Chrome, I see ASCII codes printed out properly for alphanumeric keys, but no event is received and thus nothing is printed for arrow keys.
On Firefox, I see codes printed out properly for arrow keys, but all alphanumeric keys print a keyCode of 0.

Function Names

Can you please help me understand the prolific use of a bang symbol at the end of function names. In Clojure proper this is very rarely used.

David

set-html! and event listeners

I think you should take out the line of https://github.com/levand/domina/blob/master/src/cljs/domina.cljs#L385

I think you should leave the events as they are, because let us say you had the following:

<div id="top-div">
<!-- child content -->
</div>

If you have an event listener on #top-div and you call set-html! on #top-div, those event listeners are wiped out. It seems like this doesn't need to be the case, because it's just the inner html that is getting changed, not #top-div.

(value) function returns null for <select><option>...</option></select>

Hi,

I'm trying to get the selected option from a drop down list:

`


Monday Tuesday Wednesday Thursday Friday

`

`(ns foo
(:require [domina :as dom]
[goog.dom.forms :as forms]))``

If I try get the value of the drop down using the Domina 'value' function:
(dom/value (dom/by-id "day_of_week"))

I get nil/null

If I go instead direct to the google closure getValue function:
(forms/getValue (dom/by-id "day_of_week"))

it works.

Any ideas?

by-class - domina 1.0.2-SNAPSHOT

By including domina 1.0.2-SNAPSHOT instead of 1.0.0, by-class does not work any more with the following JS message:

Uncaught Error: Doesn't support name: modern_dbg.js:17727
name modern_dbg.js:17727
domina.t3861.domina$DomContent$nodes$arity$1 modern_dbg.js:25216
nodes modern_dbg.js:25094
destroy_BANG_ modern_dbg.js:25301
remove_help modern_dbg.js:32687
(anonymous function) modern_dbg.js:26173
goog.events.Listener.handleEvent modern_dbg.js:24464
goog.events.fireListener modern_dbg.js:24798
goog.events.handleBrowserEvent_ modern_dbg.js:24919
(anonymous function)

But it works using .getElementsByClassName interop.
You can check this behaviour with the following source code included in a repo:

https://github.com/magomimmo/modern-cljs/blob/domina-by-name/src/cljs/modern_cljs/shopping.cljs

Clojure and clojurescript in 'project.clj'

Hello, is it really required to have clojure and clojurescript as dependencies in project.clj? I mean, since domina is a clojurescript library the library user will surely have both of them in their own project.clj.

Issue selecting styles

There is an issue selecting styles when the value has a : in it.
The regex match only returns the initial match before the first :.
So something like background-image: url(http://www.something.com/image.jpg) will result in a map that is {:background-image "url(http"}

Some events don't work when specified as symbols

(listen! js/document :DOMContentLoaded (fn [] (.log js/console "symbol")))
(listen! js/document "DOMContentLoaded" (fn [] (.log js/console "string")))

The second log will execute correctly when DOMContentLoaded fires (can be verified by adding a third handler using .addEventListener), the first one gets lost in an unknown void. The readme only uses symbols (even for custom events) and gives no hint that strings and symbols aren't equivalent

set-value! and value functions do not work as expected for checkboxes

Domina's set-value! doesn't work to change the value attribute of a checkbox. Looking at the code, I see this is because it's implemented by calling Google Closure Library's goog.dom.forms/setValue, whose code does not set the value of the value attribute of checkboxes, but it adds or removes the checked attribute (see the setInputChecked_ function in the same file, which, BTW, it has this comment "This seems potentially unintuitive since it doesn't set the value property").

On the other hand, Domina's value function only returns a checkbox value attribute if the checkbox is checked. Again, this is because value relies on Closure Library's equivalent function (getValue) which has this behavior for checkboxes.

I find these set-value! and value behaviors for checkboxes very uintuitive (besides, they made me waste a lot of time!) as they change the semantics of value in the HTML spec apparently for no reason.

I've raised the issue in Closure Library's mailing list but nobody replied as of now. I wonder... don't you agree that the current behavior is not correct? If so, should this be fixed in Domina, or should we wait for this to be fixed in Closure Library?

events/listen! and friends could take multiple event types

The underlying Google Closure listen method take a string or an array of strings for the event type when registering an event listener. That way, one can register the same listener function to fire on several different event types at once. This can be easily done in a (doseq), but might be nice here, too.

beta4 - Clojurescript 1069 not found in repository

Attempted to use [domina "1.0.0-beta4"], but 'lein deps' fails because:

[INFO] Unable to find resource 'org.clojure:clojurescript:pom:0.0-1069' in repository central (http://repo1.maven.org/maven2), etc

The project.clj for the beta4 version of domina has this version of Clojurescript as a dependency. I tried excluding it in my project file, e.gl.
[domina "1.0.0-beta4 :exclusions [org.clojure/clojurescript]]

guessing that domina could just use the version from cljsbuild, but that didn't work.

Is there a workaround? This version of Clojurescript doesn't seem to be available in any publc repository.

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.