This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-28
Channels
- # arachne (2)
- # aws (5)
- # aws-lambda (5)
- # beginners (4)
- # boot (25)
- # cljs-dev (270)
- # cljsjs (1)
- # cljsrn (72)
- # clojars (5)
- # clojure (201)
- # clojure-belgium (5)
- # clojure-brasil (4)
- # clojure-italy (2)
- # clojure-korea (2)
- # clojure-russia (24)
- # clojure-spec (24)
- # clojure-uk (22)
- # clojurebridge (1)
- # clojurescript (125)
- # cloverage (3)
- # cursive (41)
- # datomic (37)
- # dirac (4)
- # emacs (2)
- # hoplon (421)
- # lein-figwheel (1)
- # leiningen (5)
- # luminus (2)
- # mount (1)
- # off-topic (18)
- # om (44)
- # om-next (4)
- # onyx (44)
- # pedestal (3)
- # proton (9)
- # re-frame (21)
- # reagent (21)
- # ring-swagger (12)
- # specter (9)
- # sql (2)
- # untangled (62)
- # vim (16)
@keithsparkjoy totally tracking what you mean now, sorry for the confusion, I think it’s just a jquery issue tho the new method for setting attributes shouldnt have this problem
no there is a note in the wiki about it tho
it suggests overriding the attribute yourself
oh cool - that’s my workaround then
https://github.com/hoplon/hoplon/wiki/Raw-material#svg-viewbox-and-other-case-sensitive-attributes
that set attribute method for svg doesnt change anything tho
correct, @flyboarder
that is a better solutions for svg
i dont know if we need all those tho
yeah which should already be included in my jquery split?
since i stripped all the jquery
@flyboarder do we need svg/*? I dunno if there are any attributes with that prefix...
i think it is probably better to explicitly set it in :svg/*
but using the setAttribute method should work for you anyway
That pull request sets the SVG namespace on those attributes though - was that an oversight?
.setAttributeNS elem svgns (name kw) val)
I don’t know of any SVG attributes that have an SVG namespace
no that was intended but without jquery in core using the regular attributes :class
should work
the svg ns is still “there” technically just not explicit
I’m just thinking that you might not need all those namespace declarations for attributes because that’s a pretty rare thing
like I can’t think of any case where I would use :svg/whatever
on an attribute
agreed^
that shouldnt be, I should be able to mix attribute providers
I have working apps with those PR’s 😛
@keithsparkjoy the use case for :svg/viewBox
is this
I dont think that is the case anymore
jquery doesnt do fancy things with attributes vs properties anymore
it tells you to be better and use prop
oh thats another thing we need to fix, aset/aget is going away
they need to be exchanged for goog.object
I’m a little confused still about why you guys want to use :svg/viewBox instead of just :viewBox. Is it just so that you can route to a different multimethod or something?
because semantically it’s really confusing
yes and yes
it shouldnt be necessary tho
since jquery is no longer setting the attribute
Then please let’s call it :hack/viewBox instead
until it gets fixed the proper way?
you know what I mean?
using vanilla js
since jquery is not in core anymore
I’d really rather just use :viewBox
and have it work
one thing i definitely do not want to do is get into the browser compatibility layer game
because if I say :svg/viewBox it makes me think it has an XML namespace and it doesn't
and we propagate that myth
but then we are keeping the jquery dep
i don't want to get a bug report about some platform specific hack i need to do for some specific attribute
right makes sense, I dont think we need to change anything tho
Right - I like that better
it says what it means
whereas :svg/foo makes it seem like we’re using a namespaced attr
that’s what I meant by :hack/viewBox
It’s just a workaround for now
Thing is, all of XML is case sensitive so if jQuery is flattening attribute names they are really screwing up.
attr doesnt really do anything special
using setAttribute would be more semantically correct, what we are unknowingly supporting is setting properties
which we really dont want
because you can have both properties and attributes with the same name
for me i don't care what the underlying thing is, i just want something that makes sense
right but they are not the same, this breaks polymer for example
and webcomponents
because setting an attribute is not the same as setting a property
really we should have :attr/*
and :prop/*
for everything
hmm, if you used that how would you support something like xlink:href?
that would still need :xlink/href
you see the problem right now we are ambiguously mixing them
attributes and properties that is
true that
hehe honestly I thought that was kind of a cool feature 🙂
but I’ve not run into the collision prob
webcomponents introduces their own layer to sync the attributes and properties, jquery doesnt do this however
So I’m curious - why do you suppose :class wasn’t working inside <svg> frags?
It wasn’t being emitted at all without the little hack we introduced.
how jquery is setting the attribute
something about infered-ness in clojurescript
i don't know of anything that's been removed from clojure or broken in all the years i've been using it
yeah i dont understand the change, but I feel like “we have been warned"
@keithsparkjoy with master and svg class you should be fine with using regular attributes, the :svg/*
is for explicitly creating the attribute with the svg namespace, I think xlink is probably the only other one we need?? and can remove the rest?
not that the explicit part is needed just an option
Which attribute needs the svg namespace? I don’t know of any.
There was the xlink one - that’s the one we needed
again I dont think you “need” the ns for svg attributes it’s just there as an option
I think it’s worse than that
If you were to use it your SVG wouldn’t work
it should work, it’s the fix we came up with yesterday
The only namespace fix I was after was the xlink one
I don’t get the svg one
e.g. if you were to use :svg/viewBox it wouldn’t work
does it fail for you? that shouldnt happen
One sec, let me go see.
im going to play with your jsfiddle
There’s one that uses viewBox with the SVG namespace - :svg/viewBox.
The viewBox attribute isn’t found by the browser because it’s not looking for svg:viewBox - it’s just looking for viewBox.
it does if you look at the pull request @flyboarder sent
no worries - I’m not sure where you guys are at - so many changes happening
I just want to make it clear that if you have a function that sets attributes in the SVG namespace, it’ll effectively be dead code because nobody will be able to use it.
That xlink:href one was the rare exception
where we really do need a namespace on an attribute
right.
then we can probably revert the changes from the Prefix PR and just include the xlink one?
YES YES YES fly
that’s what I’ve been trying to say 🙂
hahahah oh gosh
I mean there may be other edge cases like that but I don’t know
longest route possible to this point XD
with vanilla js, is there a 100% compatible cross browser way of setting attributes and stuff with no special cases?
and by setting attributes i mean doing all the stuff i currently do with the jquery .attr() method
I suppose you could look at the jQuery sources to see if they have any browser specific stuff for attr()?
that is to separate from the properties
it assumes attributes are lowercase tho which is false
especially when using new stuff like webcomponents attributes and properties can both be any character, including nonvalid attribute characters like $
properties are only on the “object”
listeners are set on the object properties not attributes usually
no because attributes are not really part of the “object” as per my understanding
they are part of the object in DOM
not the JS object itself
the most visual difference is with inputs
like checkboxes and textfields
http://api.jquery.com/prop/ there is a note about attributes vs. properties
it would actually seem like using different versions of jquery provides a more inconsistent experience
and then there is .data()
I dont know that properties will actually set the “attribute” once it’s placed in a document tho
like if we set a property will it show up in page source? my instinct says no
yeah the debugger but i dont think it sets attributes at all that way
really most things should be set at attributes and select things as properties
properties are the edge case really
like I was saying there are somethings that provide syncing between attributes and properties by settings listeners during lifecycles but we dont have any of that nonsense
that has just a single method, setAttrOrPropDependingOnWhichIsTheCorrectOneForThisSpecialCase
exactly!
so there must be a library somewhere where people have figured out which permutations are setAttribute and which are properties, i hope
its a crap shoot really, i think the most sane way to handle it is by using setAttribute and then if you run into issues override the attribute method
micha if we move do! and on! that breaks existing things which have extended the attributes doesnt it?
ah ok
gotcha
that is the check jquery uses
right makes sense
awesome, im making changes to the prefix PR
for sure 😛
but i think thats less fun XD
this separation is good because now we can try other things without breaking the jq stuff
hi @chromalchemy what do you think?
Hi @micha ! I need to (always) catch up. You guys are awesome, always blowing my mind and thinking of everything 🙂
I have a hopefully simple question: How can can a custom element use a value from a from a for-tpl
in an attribute function. Like
(for-tpl [x [1 2]] (custom-elem :click #(+ 10 x)))
Whoops, that example works fine, but what about if the function is defined in the defelem.
(defelem custom-elem [x] (div :click #(+ 1 x))) (for-tpl [x [1 2]] (custom-elem :value x))
the x
does not seem to inherit through the custom element
I got it now. Needed to define the variable as attribute in the defelem
:
(defelem elem [{:keys [value] } kids]
(div :click #(prn value) kids))
(defelem mylist []
(for [x ["Hello" "World"]]
(elem :value x x)))
Or
(defelem elem [{:keys [value] } kids]
(div :click #(prn value) kids))
(defelem mylist []
(for-tpl [x ["Hello" "World"]]
(elem :value @x x)))
I assume for-tpl
is more appropriate when dealing with elements, for the potentially dynamic manipulation...
@chromalchemy precisely
@micha question for you, since elements implement a custom protocol should we move -set-attributes!
and -set-styles!
to hoplon.jquery
? This way if you are using jquery you are setting the styles and attributes with the old jquery methods?
I was thinking of providing :attr/*
:prop/*
and :data/*
to explicitly set those with the jquery methods
that way if you run into a conflict on the js object you have a way to set the one you wanted
basically the provider implements the custom protocol for attributes and styles instead of core implementing it
i think the protocol should be doing the current thing, because that's important for compatibility with 3rd party plugins
Hey guys, I just discovered that it’s not jQuery that’s lower-casing attribute names on us.
It’s the DOM.
Get this - there’s a rule in XHTML
that says all attributes must be lowercase
so the DOM appears to be enforcing this
HOWEVER
SVG docs are in a different namespace
So the DOM doesn’t do that there.
“XHTML documents must use lower case for all HTML element and attribute names. This difference is necessary because XML is case-sensitive e.g. <li> and <LI> are different tags. "
So my guess is that jQuery isn’t doing any lowercasing at all
…and it should just work.
I think HTML5 docs follow those same rules
Regardless - the DOM is definitely doing something different
When you call setAttribute within an HTML5 element, it lowercases the attribute name
personally i think case insensitive is a good choice, and svg is being weird, but yeah that is irrelevant 🙂
XML is case sensitive
For example, if you say <div Class=“foo”> the DOM will lowercase “Class” for you.
Because Class and class are different
Not sure that’s the best behavior because it’s a band-aid for incorrectly written HTML
but that seems to be the behavior
So anyway, I don’t think getting rid of jQuery is going to solve that problem. Arguably there shouldn’t even be a problem.
with viewBox etc.
So the note on the wiki about case sensitive attributes is a bit misleading
but jquery is indeed lowercasing things, I checked the code
Interesting.
it assumes attributes are lowercase if it cant find a property
The DOM messes with case too - https://jsfiddle.net/me5sror9/
Okay so HTML5 is not XML then. Interesting.
But SVG definitely is.
If you mess up the case on SVG attributes they won’t work properly.
True that.
So jQuery is just overstepping their bounds by always lowercasing.
Gosh I wonder if some DOM implementations don’t do that
so jQuery is trying to normalize things
e.g. maybe IE doesn’t lowercase for you
so they do it.
Although that’s just weird - if case doesn’t matter why would anybody lowercase?
for consistency?
@keithsparkjoy there is a note about IE9 doing memory leaks
figures
we're coming in at a lower level than HTML, it's weird that we need to even know about it
well the HTML spec matters when you’re working with the DOM, no?
I mean, if they say it’s case insensitive, then Class is the same as class, even with the DOM
XHTML is an implicit spec on the DOM
with HTML5
but i think it is still applied when objects are inserted into the DOM
Mind if I update that wiki note with this new information?
Just so it doesn’t confuse people?
@micha so that PR adds the :prop/*
and :data/*
options, plus restores attribute behaviour to jquery while leaving core alone
which part?
well the version in core uses vanilla js as per the jq split, but the version in jquery will do the prop and node type checking which is what you wanted no?
the (defmethod do! :attr
in the jquery ns doesn't need to call set-attributes!
was what i was suggesting
ah ok i can fix that
mhm, yeah we dont really want to adjust it for the provider since it’s global
@micha fixed!
@keithsparkjoy can you verify this fails the way you would expect, i added jquery
Nope - that looks different. The attribute Bar didn’t even get put on the circle as far as I can see
Is that what you are seeing?
sorry forgot the “#” character
No worries - do a update and send the new link
nm I fixed it 🙂
Okay yea now it’s doing exactly what I was seeing
it’s lowercasing when it shouldn't
so it’s jquery lol
Right. I did some additional research and it sounds like the jQuery guys just didn’t care to deal with SVG attributes
that is essentially what hoplon is doing internally
yeah nor did they provide an .svg()
method to take care of it
There’s all sorts of noise on StackOverflow with guys using jQuery with SVG and having this problem
glad we are fixing this up, should make things “just work” in the future
yea, appreciate your help with all of this, and your patience
np sorry yesterday took so long to get on the same page
i totally forgot your version would be using attr instead of setAttribute
What is the point of (dissoc attrs :foo)
in this pattern?
(defelem elem [{:keys [foo] :as attrs}]
(div (dissoc attrs :foo) foo))
(for-tpl [x ["Hello" "WORLD"]]
(elem :foo @x))
(defelem titled-list
[{:keys [title] :as attr} kids]
(div
(dissoc attr :title)
(h2 :text title)
(ul (map li kids))))
Hmm. I see that it works, but still not seeing the purpose of (dissoc)
. If I use plain attr
it also works. Also, if I (dissoc :class)
, then I effectively disable the :class
declaration when I instantiate the element. But (dissoc :title)
enables the :title
declaration on the element instance.. This feels like inverse behaviors for different keywords?
Maybe I'm thinking of dissoc
in the negative, where it really means in this context "enable the use of this keyword on this element invokation"
title in the example above is coming from parameters
This seems to work, without dissoc
, so I guess I'm missing some of the nuance.
(defelem titled-list
[{:keys [title] :as attr} kids]
(div attr
(h2 title)
(ul (map li kids))))
(titled-list
:class "large"
:title "my things"
"one" "two" "three")
the difference is that the title entry in attr is removed with dissoc
(def my-map {:a 1 :b 2 :c 3 :title "hi!”})
(dissoc my-map :title)
=> {:a 1, :b 2, :c 3}
oh whoops, what @flyboarder said
no thats a much better example
1 liner 😉
I understand what the function does. Buy why remove the keyword from attrs
in that spot, when in practice you are using that keyword in the element invocation?
sorry for being dense 😛
there is no real value to it in html, you could leave it if you wanted, but usually when your attribute contains an object you want to remove it
like a formula cell or some complex data
also i don't want to have a title
attribute on the div that's created by the titled-list
function
<div class="large" title="my things">
<h2>my things</h2>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</div>
<div class="large">
<h2>my things</h2>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</div>
that is what i want when i do (titled-list :class "large" :title "my things" "one" "two" "three")
this would also be a problem if instead of div
my defelem would do somethign like this:
(defelem titled-list
[{:keys [title] :as attr} kids]
(foop
(dissoc attr :title)
(h2 :text title)
(ul (map li kids))))
that's if foop
also has a :title
attribute that maybe does somethign completely different
Ok, I got it now. I wasn't inspecting the html output carefully and seeing that difference. I was assuming dissoc
had more to do with enabling or disabling keyword usage when using custom elements. Like if in defelem
you needed to override subsequent usage of particular keyword .
Thanks @micha @flyboarder! for taking to time to spell it out so carefully 🙂
the purpose there is usually to allow the user to include other attributes as well as the ones that your defelem knows about
that's why it's common to remove the attributes your defelem handles from the attribute map, and apply that to the returned component
And by returned component, you mean the html output?
@chromalchemy defelem doesnt return html output but a DOM element