Using Polymer With Om or Freactive

431 views
Skip to first unread message

Timothy Washington

unread,
Dec 16, 2014, 4:20:21 PM12/16/14
to clojur...@googlegroups.com
Has anyone gotten Om or Freactive to work with Polymer components? 

Om currently requires use of the React.DOM API. And hiccup or enlive style templating for Om, doesn't seem to support polymer, or any web components. Let me know if I'm missing something. 

I got a little further with Freactive. However Polymer has these kind of pseudo attributes without keys (in bolded blue). First of all, what are those? And secondly, can we generate them with Freactive's template model? My attempt is the hiccup like syntax in landing.cljs, which does not generate the desired html (missing the blue keys). 


landing-body.html 

<core-header-panel flex>
  <core-toolbar layout>
    <div class="tk-lust-script header-logo">fubar</div>
    <div class="tk-open-sans header-text">fubar</div>
    <span flex>&nbsp;</span>
    <div class="tk-open-sans header-text" id="signout">logout</div>
  </core-toolbar>
  ...
</core-header-panel>

landing.cljs

(defn view []
  [:core-header-panel flex
      [:core-toolbar layout
        [:div { :class "tk-lust-script header-logo" } "fubar"]
        [:div { :class "tk-open-sans header-text" } "fubar"]
        [:span flex "&nbsp"]
        [:div { :class "tk-open-sans header-text" :id "signout" } "logout"]]

      ...])

(defonce
  root
  (dom/append-child! (.-body js/document)
                     [:div#app]))

(dom/mount! root (view))


Thanks 

Tim Washington 


Timothy Washington

unread,
Dec 16, 2014, 5:33:29 PM12/16/14
to clojur...@googlegroups.com
Ok, I figured out that these <core-header-panel flex> tags are HTML5 boolean attributes (see here and do a "boolean" text search here). 

I don't see an actual definition anywhere, just code and markup that refers to them. And browsers definitely respond to them. So with that, is there a way to generate them, using hiccup, enlive or enfocus? I don't see that feature in those libs. 

The ideal would be i) enlive-stlye templating, that works with ii) Om (or Freactive, Reagent or Quiescent), and iii) web components (Polymer et al.), respecting iv) HTML5 boolean attributes, which Polymer uses. But I can compromise, requiring mainly Polymer and HTML5 boolean attributes. Has anyone gotten close to this combination? 


Thanks 

Tim Washington 

Ruslan Prokopchuk

unread,
Dec 17, 2014, 9:42:11 AM12/17/14
to clojur...@googlegroups.com
I use Polymer with Freactive, and represent <core-header-panel flex> as [:core-header-panel {:flex 1}] This is not beautiful, but works.

Timothy Washington

unread,
Dec 17, 2014, 7:03:27 PM12/17/14
to clojur...@googlegroups.com
Hmm, 

For me A) just produces B). I'm using [freactive "0.1.0"]. I'm guessing attribute properties are bound here, which uses this setter function. But I could be wrong. Trying to find any other place, like some global flag , that could produce that. 

A) [:core-header-panel {:flex 1} ....]

B) <core-header-panel flex="1">...</core-header-panel>


Hmm 

Tim Washington 

Aaron Craelius

unread,
Dec 17, 2014, 8:03:56 PM12/17/14
to clojur...@googlegroups.com
See this about boolean attributes: http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-attributes

It would seem that the most correct thing would be {:flex true}

Since setAttribute takes a string value (http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-F68F082) and freactive should convert true to the string "true", this should work. Let me know if not.

Ruslan Prokopchuk

unread,
Dec 18, 2014, 8:33:34 AM12/18/14
to clojur...@googlegroups.com
No, correct way (accordingly to Aaron's link) is to write {:flex "flex"} or {:flex :flex}, not {:flex true}. But setting any value to boolean attribute will work in real world, so 1 is short to type, and I prefer it over valid markup ;-)

Ruslan Prokopchuk

unread,
Dec 18, 2014, 8:36:39 AM12/18/14
to clojur...@googlegroups.com
четверг, 18 декабря 2014 г., 16:33:34 UTC+3 пользователь Ruslan Prokopchuk написал:
> No, correct way (accordingly to Aaron's link) is to write {:flex "flex"} or {:flex :flex}, not {:flex true}. But setting any value to boolean attribute will work in real world, so 1 is short to type, and I prefer it over valid markup ;-)

Oh, also empty string is correct: {:flex ""}. If your editor will complete second " for you, it almost as short to type as using number, but will satisfy spec.

Timothy Washington

unread,
Dec 18, 2014, 9:56:24 AM12/18/14
to clojur...@googlegroups.com
Sweet. That seems to have done the trick. {:flex ""} (or {:flex "flex"}, {:flex :flex} work as well). 

Now however, looks like mounting the :core-header-panel in the html > body, only works in Chrome (on OSX). The clojurescript calls don't seem to work in FireFox or Safari. See below screenshots of browsers, with inspectors. Chrome has the tag attached, whereas the same page in the other browsers, doesn't attach the tag. Is there anything there I can be doing to make this work across browsers? 

(defn view []
    [:core-header-panel { :flex true } ... )

(dom/mount! (.-body js/document) (view))

Inline image 1
Inline image 2
Inline image 3

Tim Washington 

Ruslan Prokopchuk

unread,
Dec 18, 2014, 11:25:46 AM12/18/14
to clojur...@googlegroups.com
Did you include webcomponents.js polyfill?

I use smth like

[:script {:src "bower_components/webcomponentsjs/webcomponents.js"}]
(for [s ["core-elements" "paper-elements" "fontawesome-iconset-svg"]]
[:link {:rel "import" :href (str "bower_components/" s "/" s ".html")}])


--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/aBF1U8hQkpQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Ruslan Prokopchuk

unread,
Dec 18, 2014, 11:26:28 AM12/18/14
to clojur...@googlegroups.com

Aaron Craelius

unread,
Dec 18, 2014, 12:14:17 PM12/18/14
to clojur...@googlegroups.com
Oops! I guess I misinterpreted that... Do you think there's any sense in adding special handling for this case? You can see someone asked for special handling for checkbox checked: https://github.com/aaronc/freactive/blob/master/src/clojure/freactive/dom.cljs#L345-L347. But maybe this should be the user's responsibility to know the HTML spec and not freactive's? I don't want get-attr-setter to become very complex...

Timothy Washington

unread,
Dec 18, 2014, 12:17:31 PM12/18/14
to clojur...@googlegroups.com
Yeah, the "<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>" is baked into in the :head of the document. Including it in the dom/mount! call doesn't help, as that's not getting attached in FireFox and Safari. 


Tim Washington 

Ruslan Prokopchuk

unread,
Dec 18, 2014, 2:11:04 PM12/18/14
to clojur...@googlegroups.com
Works in my Firefox 34.0 on Linux. Does page produce any errors in Console?

Timothy Washington

unread,
Dec 18, 2014, 2:33:30 PM12/18/14
to clojur...@googlegroups.com
Yes, you're right. On my OSX system, Firefox and Safari consoles show an "Error: Assertion failed" in webcomponents.min.js. That error doesn't happen in Chrome. If that's working for you in FF / Linux, I don't know of a reliable way of making the mounting work across platforms (a big reason of why I'm using Polymer). Have you tried your code on a Mac?

Inline image 1
Inline image 2


Tim Washington 

Ruslan Prokopchuk

unread,
Dec 18, 2014, 2:39:19 PM12/18/14
to clojur...@googlegroups.com
No, I have no Mac near me to test. But I had problems in Firefox with clojurescript: haven't figured why, it loaded messed up content by assets links (e.g. normalize.css instead of webcomponents.js, different compiled files in wrong order etc.). I have deleted Firefox profile folder and started it clean and everything get to work.

Timothy Washington

unread,
Dec 18, 2014, 3:54:13 PM12/18/14
to clojur...@googlegroups.com
A clean clojurescript build didn't help. But base on this Polymer issue, I did get a bit further. 

I changed this:

(dom/mount! 
  (.-body js/document)
  (view)) 

To this: 

(dom/mount! 
  (.querySelector js/document "body") 
  (view)) 

... And at the very least got the scaffold mounting (see below screenshot). But internally, I think Freactive (as well as most libs) is accessing nodes in a way that webcomponents.js doesn't like, So it doesn't look like I can safely use Polymer with Freactive. Idon't think it's a Clojurescript error. That "Error: Assertion failed" goes away altogether if I remove the (dom/mount! (.-body js/document) (view)) call. For those joining this thread. These are some references on what polyfills are. 

Inline image 1

Aaron Craelius

unread,
Dec 18, 2014, 4:53:13 PM12/18/14
to clojur...@googlegroups.com
Hi Timothy, so before we conclude that it's not possible - let's look into it a little bit more. Could you possibly post stack traces for those exceptions? If it doesn't work out of the box, we can probably add a plugin to freactive to support these cases.

Timothy Washington

unread,
Dec 19, 2014, 9:41:36 AM12/19/14
to clojur...@googlegroups.com
Hi Aaron, sure thing. 

A) In both browsers, there was an "HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy". 

B) And then a "TypeError: Polymer is not a function". This bubbles up from an anonymous constructor function (when evaluating 'Polymer'), from each Polymer component I'm trying to use. For example: 

(function() {
  Polymer('core-toolbar', { ... } ) } )  // calling the Polymer function is what throws the error. 

Neither error, in neither browsers, produced a stacktrace. So that screenshot is pretty much all there is. And again, it's happening when I try to dom/mount! the hiccup'd representation of my node tree. 

(defn view []                                                                                              
  [:core-header-panel { :flex true } ... ])


I'm happy to describe further if needed. 


Tim Washington 


You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.

Aaron Craelius

unread,
Dec 19, 2014, 10:24:27 AM12/19/14
to clojur...@googlegroups.com
Is it possible you could produce a minimal failing example and post on github for me to try out? I have OS X. 

Timothy Washington

unread,
Dec 19, 2014, 10:40:15 AM12/19/14
to clojur...@googlegroups.com
Sure thing. Go to the feature-state-management branch of this github repo

Clone it, and run `lein ring server-headless`. Then go to `localhost:3000/landing.html` in your browser. For me, it works in Chrome, but fails in Firefox and Safari. All polymer components should be on your file system. Let me know if you have any problems. 


Tim Washington 


Aaron Craelius

unread,
Dec 19, 2014, 11:01:44 AM12/19/14
to clojur...@googlegroups.com
Okay, missing a dependency:
Could not find artifact bkell:bkell:jar:0.1.0-SNAPSHOT in clojars (https://clojars.org/repo/)

Aaron Craelius

unread,
Dec 19, 2014, 11:11:26 AM12/19/14
to clojur...@googlegroups.com
Also, have you verified in these browsers that you can create Polymer elements using Javascript - i.e. document.createElement(...)?

Timothy Washington

unread,
Dec 19, 2014, 11:53:49 AM12/19/14
to clojur...@googlegroups.com
Ah, shoot. Ok, so I've released bkell 0.1.0 to clojars (SNAPSHOT got trampled) (see here and here). So just change that. 

As far as javascript creating Polymer elements, theoretically, there shouldn't be a problem. If I can call `document.createElement("fubar")`, then I should be able to call `document.createElement("my-custom-component")` . For example, these work in Chrome, Firefox and Safari. 

document.createElement("div")
<div>​</div>​

document.createElement("fubar")
<fubar>​</fubar>​

document.createElement("my-custom-component")
<my-custom-component>​</my-custom-component>​

document.createElement("core-header-panel")
<core-header-panel>​</core-header-panel>​


Tim Washington 


Timothy Washington

unread,
Dec 20, 2014, 12:24:54 PM12/20/14
to clojur...@googlegroups.com
Here's maybe a bit more insight into why evaluating Polymer(...) gives "TypeError: Polymer is not a function". This is confusing, because i) the Polymer() function / object is definitely available in all browser js consoles. ii) And even calling Polymer() in Chrome fails. But if I first import this: 

<link rel="import" href="bower_components/polymer/polymer.html">

A) Then I can call Polymer() in Chrome (and Opera). However, I need to call Polymer.__proto__.constructor() in Firefox and Safari. Looks like others have wrestled with this too. So it seems the Chrome family of browsers have some extra shims and code to handle Polymer objects. Firefox and Safari are close, but are somehow unable to call Polymer directly, without reaching into the __proto__.constructor. 

B) I also tried waiting for the polymer-ready event before manipulating any of the DOM or setting CoreStyle properties (to no avail). Obviously I don't need to do this on Chrome, because native HTML imports work a little differently. But definitely not on Firefox or any browser without native HTML imports (see here).

C) And remember that it's each component, trying to instantiate itself, that throws the error. 

(function() {
  Polymer('core-toolbar', { ... } ) } )  // calling the Polymer function is what throws the error. 


Hth 

Tim Washington 

Aaron Craelius

unread,
Dec 20, 2014, 1:43:04 PM12/20/14
to clojur...@googlegroups.com
If I remove the [:script ...] line after [:core-header-panel ...] in view it seems to appear the same in all browsers and I don't see errors in the console.

Timothy Washington

unread,
Dec 20, 2014, 4:29:36 PM12/20/14
to clojur...@googlegroups.com
Niiice, that does the trick. 

A double-import. I've been looking at the code too long. Thank-you brother ! 


Tim Washington 

Aaron Craelius

unread,
Dec 20, 2014, 7:22:38 PM12/20/14
to clojur...@googlegroups.com
You're welcome!

I'll be curious to know how/if this works out for you.

Good luck!

Reply all
Reply to author
Forward
0 new messages