Fork me on GitHub
#hoplon
<
2015-09-07
>
micha15:09:56

@onetom: i have some ideas about CSS in hoplon if you want to discuss

micha15:09:05

i mean transitive css via cljsjs

onetom15:09:55

not sure what do u mean by "transitive css via cljsjs"

micha15:09:11

you were asking about getting css from cljsjs packages, right?

onetom15:09:04

yes. i was wondering if i can get rid of the environment specific sifting... it's ugly coupling between the cljsjs packages and the boot tasks..

micha15:09:31

and the main problem is that transitive deps are broken with respect to css

micha15:09:53

it's crucial that transitive dependencies are handled by tha dependency resolution machinery

micha15:09:55

and not manually

micha15:09:59

like the cljs is

micha15:09:12

if you depend on package A which in turn depends on package B

micha15:09:15

for example

micha15:09:30

if you need to manually include B you're screwed

micha15:09:44

if you even need to know about B for A to work you're screwed

micha15:09:54

instant dependency hell

micha15:09:18

the package abstraction would be a sham, then

micha15:09:33

if you need to handle transitive deps manually then you don't really have packages

micha15:09:39

you have bags of things

micha15:09:15

so the problem with CSS is, how to handle transitive CSS dependencies automatically?

micha15:09:39

i think the solution is to make CSS into executable code

micha15:09:52

i.e. make a namespace for the css that you can require in your cljs namespaces

micha15:09:13

when you require the namespace it creates a <style> tag perhaps

micha15:09:29

this would ensure that they are installed in the correct dependency order

micha15:09:35

and only when actually used

micha15:09:11

and it gives full control over all the details, like different CSS for rtl languages, CSS theme stuff, etc

micha15:09:08

i added a secret thing to boot-hoplon last night btw

micha15:09:17

an undocumented feature

micha15:09:47

boot hoplon --refers adzerk.cljs-console --refers cljs.test

micha15:09:08

this will refer in all the vars from those namespaces into all .hl namespaces

micha15:09:36

but i didn't really take the time to make it 100% foolproof so it's undocumented

micha15:09:51

like if you refer in namespaces that define the same names

micha15:09:00

there will be a collision that isn't handled

micha15:09:22

but i use it to import my logging library for example

micha15:09:48

because i don't want anyone using pr or console.log in my app cause that always ends up in production by mistake

micha15:09:16

but requiring that people add extra libs to the ns :requires is too much

micha15:09:31

like you want to get in, add some logging real quick and test something

onetom15:09:24

i saw your conversations about spy->

onetom15:09:30

where is that defined?

onetom15:09:48

i miss that capability a lot... it's build in to rebol for example

onetom15:09:11

http://www.rebol.com/docs/words/wprobe.html

if probe now/time > 12:00 [print "now"]

micha15:09:33

it's in the cljs-console project

onetom15:09:45

u can just drop in the middle of any expression and it prints the expression at that point without affecting the behaviour

micha15:09:57

yeah that's sweet!

micha15:09:12

spy-> is sort of like that

micha15:09:25

it logs its argument and then returns it

micha15:09:40

so you can wrap any expression with spy-> or spy->>

micha15:09:57

since it also supports a message to accompany the value

micha15:09:09

you need one that takes the message first and another that takes the message last

micha15:09:24

so you can thread it in the -> and ->> threading macros

micha15:09:46

(-> foo bar (spy-> "the value is") baz)

micha15:09:57

(->> foo bar (spy->> "the value is") baz)

onetom15:09:55

there it is, u just documented it.

onetom16:09:40

boot-hoplon 0.1.8 works. it's going into production. (or at least onto our master branch simple_smile

micha16:09:52

:thumbsup:

micha16:09:22

this css in js slide deck is interesting

micha16:09:37

it's sort of like what i was describing

onetom16:09:49

yup. it is very much like that.

micha16:09:50

but the immediate problem to solve is the simpler one

onetom16:09:58

they are using inline styles though

micha16:09:16

we don't really need dead css elimination or classname minification right now

micha16:09:24

we can do that for new code

micha16:09:39

what we need to solve is the problem of interop with existing js things that need their own css

micha16:09:47

like a datepicker for instance

micha16:09:02

i think we can solve this problem elegantly

micha16:09:28

like i had to incorporate the jquery ui datepicker into my application the other day

micha16:09:36

it involved js and css

micha16:09:48

and the js depends on other js

onetom16:09:07

im still not sure how that looks like because they mentioned something like "we give a reference to a rule that's somewhere else in the file" not sure what file are they talking about really... js or css file? 😕

micha16:09:28

i don't think i'm at that slide yet

onetom16:09:07

so the js dependencies are already solved with cljsjs, right?

onetom16:09:23

like jquery will be initialized 1st and wont be loaded twice

micha16:09:06

so for all of these cases you do the same thing

micha16:09:09

or i do anyway

micha16:09:20

i make a cljsjs package for the 3rd party js+css

micha16:09:36

now at least there is an artifact id and version associated with it

micha16:09:48

so we can specify it precisely

micha16:09:18

the cljsjs package specifies any dependencies the thing might have on other packages

micha16:09:22

so that's good to go

micha16:09:34

when that's done i make my hoplon wrapper for it

micha16:09:53

that either provides a custom element or a custom attribute, depending on what the js is doing

micha16:09:01

or amybe provides both

micha16:09:32

in my hoplon wrapper i need to do :require [cljsjs.jquery-ui] to load the js

micha16:09:59

so now i have a (datepicker ...) element i can use

micha16:09:38

and in my application i just do :require [hoplon.contrib.datepicker :refer [datepicker]] or something like that

micha16:09:52

so in my application code i don't need to know anything about jquery ui

micha16:09:12

that's all handled at the wrapper level which i pull in from clojars

micha16:09:25

but then there's the css

micha16:09:53

which i need to investigate all the dependencies of dependencies and include in my css build step manually

micha16:09:59

this is bullshit

micha16:09:25

however, suppose the datepicker has some css it depends on

onetom16:09:24

we are on the same page until now

micha16:09:51

this namespace can be autogenerated

micha16:09:19

so now in our hoplon wrapper we simply :require [datepicker.css.default]

micha16:09:39

it's handled automatically now, and transitive dependencies also handled

micha16:09:52

and the css is not included unless it needs to be

micha16:09:17

so if you don't use the datepicker you won't have the datepicker css in your application

micha16:09:21

and if you do then you do

micha16:09:15

we can also support themes, whatever

micha16:09:37

like suppose you have two different css themes, "silver" and "gold"

micha16:09:43

and a base css

micha16:09:02

you just make datepicker.css.silver and datepicker.css.gold namespaces

onetom16:09:11

so the "...css rules here..." part would be slurped from the cljsjs/development/datepicker.css ?

micha16:09:13

each of which :requires datepicker.css.base

micha16:09:23

there is probably a more clever way to implement it than what i wrote there

micha16:09:29

but this is the simplest implementation

micha16:09:36

and it demonstrates the concept

micha16:09:46

we need to bring css into the js dependency graph

micha16:09:56

so we can handle transitive deps properly

micha16:09:40

we could do static analysis too

micha16:09:51

and figure out which css will be needed and in which order

micha16:09:05

by examining the cljs analyzer output

micha16:09:21

then we could concatenate that with the rest of our css or whatever

micha16:09:23

at build time

micha16:09:21

or probably using the prerendering to figure it out

micha16:09:36

if it marks the style tags it creates somehow

micha16:09:43

so we can see them when we prerender

micha16:09:06

we could then take advantage of the google closure tree shaking to the fullest

micha16:09:56

i'm starting to realize that prerendering is a crucial step of the process

micha16:09:06

it essentially gives us a 2 pass compiler

micha16:09:10

which is really powerful

micha16:09:50

like we can run the program after goog optimizes it

micha16:09:00

and use the output to modify things

onetom16:09:00

sounds good, but the details i beyond me at the moment. i looked into your latest commit but i can't really understand it at 1st glance. u r getting the publics to be included into the .hl from the cljs analyzer vs parsing the hoplon.cljs source?

micha16:09:18

well the analyzer is parsing it now

micha16:09:21

which is more robust

micha16:09:26

it actually evaluates it now

micha16:09:55

so it should work with almost any namespaces now

micha16:09:32

it shouldn't really have any effect on your code

micha16:09:39

it should do the same thing in the end

micha16:09:57

i just wanted a way to shim in other namespaces there

micha16:09:16

and the cljs-console one does lots of metaprogramming, like macros that define macros and so on

micha16:09:35

so it wasn't really possible to do static analysis on it

micha16:09:17

like sniffing for defmacro was useless there

micha16:09:47

because none of the macros i'm interested in exist until the namespace is compiled

onetom16:09:45

(ns hoplon.app-pages._index_DOT_html (:require [homepage.layout :refer [section-header] :as layout]
...
[javelin.core :refer [^{:file "file:/Users/onetom/.m2/repository/javelin/javelin/3.8.1/javelin-3.8.1.jar!/javelin/core.cljs", :line 71, :column 10, :end-line 71, :end-column 14, :protocols #{cljs.core/IWatchable cljs.core/IReset cljs.core/ISwap cljs.core/IMeta cljs.core/IDeref cljs.core/IPrintWithWriter cljs.core/IWithMeta}, :skip-protocol-flag #{cljs.core/IWatchable cljs.core/IReset cljs.core/ISwap cljs.core/IMeta cljs.core/IDeref cljs.core/IPrintWithWriter cljs.core/IWithMeta}, :factory :positional, :arglists (quote ([^{:file "file:/Users/onetom/.m2/repository/javelin/javelin/3.8.1/javelin-3.8.1.jar!/javelin/core.cljs", :line 71, :column 16, :end-line 71, :end-column 20} meta ^{:file "file:/Users/onetom/.m2/repository/javelin/javelin/3.8.1/javelin-3.8.1.jar!/javelin/core.cljs", :line 71, :column 21, :end-line 71, :end-column 26} state ^{:file "file:/Users/onetom/.m2/repository/javelin/javelin/3.8.1/javelin-3.8.1.jar!/javelin/core.cljs", :line 71, :column 27, :end-line 71, :end-column 31} rank

micha16:09:03

whoa what is that

onetom16:09:47

it's the generated hoplon (page "index.html") ns form

micha16:09:00

need to remove the metadata

micha16:09:17

it shouldn't hurt anything, but it's ugly and useless

onetom16:09:19

looked scary at 1st simple_smile

onetom16:09:40

also there are bunch of empty lines after the ns form

onetom16:09:43

why is that?

micha16:09:58

that's so the line numbers in the cljs file match with the ones in the .hl file

micha16:09:15

like if you get an error on line 100 of indexDOT_html.cljs or whatever

micha16:09:24

that's line 100 of index.cljs.hl too

onetom16:09:02

ok, that's what i suspected too

micha16:09:05

any errors you get int he namespace declaration are reported as line 1

micha16:09:12

so it doesn't matter what i do there

onetom16:09:13

interesting hack simple_smile

micha16:09:44

i would like to get source maps going someday

micha16:09:52

so you can see the .hl file in the dev tools

micha16:09:59

this is the first step i think

onetom16:09:24

im happy with seeing the generated cljs file...

micha16:09:37

that should be much better now, too

micha16:09:46

it no longer parses anything but the first form

micha16:09:49

the ns declaration

micha16:09:55

the rest is left as you wrote it

micha16:09:00

including whitespace etc

onetom16:09:03

sometimes i would like to see though the code generated from it and i haven't found any way to switch to that

micha16:09:18

yeah that's super annoying

onetom16:09:20

other than browsing thru the source tab in the chrome dev tools...

micha16:09:24

i would also like to see that

micha16:09:39

i just turn off source maps in the dev tools

micha16:09:42

and reload the page

onetom16:09:43

ok, so im not alone at least simple_smile

micha16:09:50

annoying but i don't know a better way

onetom16:09:08

ah, so u can turn off source maps... now ive learnt something simple_smile

micha16:09:29

hm, i hope they didn't remove that

micha16:09:34

i haven't done it in a while

onetom16:09:16

btw, the [adzerk/boot-reload "0.3.2"] plugin somehow broke on my code. it falls into an infinite external script loading...

onetom16:09:43

have u experienced anything like that before?

micha16:09:44

i'm using 0.3.1

micha16:09:51

i haven't seen that behavior before

onetom17:09:49

i've experienced it with both 0.3.1 and 0.3.2

onetom17:09:10

btw, just for the record, i found out about that css in js slide deck from http://react.rocks/example/radium