├── .gitignore
├── Readme.md
├── assets
├── css
│ └── obsidian.css
├── img
│ ├── background.jpg
│ └── silhouette_dune_desktop.jpg
├── index.jade
├── js
│ ├── core.ls
│ ├── entry.ls
│ ├── lib.ls
│ ├── site.ls
│ └── test.ls
└── less
│ └── main.less
├── bower.json
├── complete-deploy
├── config.ls
├── dist
├── css
│ └── vendor.css
└── img
│ ├── background.jpg
│ └── silhouette_dune_desktop.jpg
├── gulpfile.ls
├── lib
└── dyncss.js
├── package.json
└── vendor
└── less-elements.less
/.gitignore:
--------------------------------------------------------------------------------
1 | bower_components
2 | bower_components
3 | status
4 | _site
5 |
6 | dist/css/client.css
7 |
8 | dist/css/client.css
9 |
10 | dist/html/index.html
11 |
12 | dist/index.html
13 |
14 | dist/js/client.js
15 |
16 | dist/js/client.js
17 |
18 | dist/js/client.js
19 |
20 | dist/index.html
21 |
22 | dist/html/index.html
23 |
24 | dist/css/client.css
25 |
26 | dist/css/client.css
27 |
28 | dist/html/index.html
29 |
30 | dist/index.html
31 |
32 | dist/js/client.js
33 |
34 |
35 | dist/js/vendor.js
36 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 | # DynCSS
3 |
4 | Make your site come to life with [Dynamic CSS](http://www.vittoriozaccaria.net/dyn-css).
--------------------------------------------------------------------------------
/assets/css/obsidian.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Obsidian style
3 | * ported by Alexander Marenin (http://github.com/ioncreature)
4 | */
5 |
6 | .hljs {
7 | display: block; padding: 0.5em;
8 | background: #282B2E;
9 | }
10 |
11 | .hljs-keyword,
12 | .hljs-literal,
13 | .hljs-change,
14 | .hljs-winutils,
15 | .hljs-flow,
16 | .lisp .hljs-title,
17 | .clojure .hljs-built_in,
18 | .nginx .hljs-title,
19 | .css .hljs-id,
20 | .tex .hljs-special {
21 | color: #93C763;
22 | }
23 |
24 | .hljs-number {
25 | color: #FFCD22;
26 | }
27 |
28 | .hljs {
29 | color: #E0E2E4;
30 | }
31 |
32 | .css .hljs-tag,
33 | .css .hljs-pseudo {
34 | color: #D0D2B5;
35 | }
36 |
37 | .hljs-attribute,
38 | .hljs .hljs-constant {
39 | color: #668BB0;
40 | }
41 |
42 | .xml .hljs-attribute {
43 | color: #B3B689;
44 | }
45 |
46 | .xml .hljs-tag .hljs-value {
47 | color: #E8E2B7;
48 | }
49 |
50 | .hljs-code,
51 | .hljs-class .hljs-title,
52 | .hljs-header {
53 | color: white;
54 | }
55 |
56 | .hljs-class,
57 | .hljs-hexcolor {
58 | color: #93C763;
59 | }
60 |
61 | .hljs-regexp {
62 | color: #D39745;
63 | }
64 |
65 | .hljs-at_rule,
66 | .hljs-at_rule .hljs-keyword {
67 | color: #A082BD;
68 | }
69 |
70 | .hljs-doctype {
71 | color: #557182;
72 | }
73 |
74 | .hljs-link_url,
75 | .hljs-tag,
76 | .hljs-tag .hljs-title,
77 | .hljs-bullet,
78 | .hljs-subst,
79 | .hljs-emphasis,
80 | .haskell .hljs-type,
81 | .hljs-preprocessor,
82 | .hljs-pragma,
83 | .ruby .hljs-class .hljs-parent,
84 | .hljs-built_in,
85 | .sql .hljs-aggregate,
86 | .django .hljs-template_tag,
87 | .django .hljs-variable,
88 | .smalltalk .hljs-class,
89 | .hljs-javadoc,
90 | .django .hljs-filter .hljs-argument,
91 | .smalltalk .hljs-localvars,
92 | .smalltalk .hljs-array,
93 | .hljs-attr_selector,
94 | .hljs-pseudo,
95 | .hljs-addition,
96 | .hljs-stream,
97 | .hljs-envvar,
98 | .apache .hljs-tag,
99 | .apache .hljs-cbracket,
100 | .tex .hljs-command,
101 | .hljs-prompt {
102 | color: #8CBBAD;
103 | }
104 |
105 | .hljs-string {
106 | color: #EC7600;
107 | }
108 |
109 | .hljs-comment,
110 | .java .hljs-annotation,
111 | .hljs-blockquote,
112 | .hljs-horizontal_rule,
113 | .python .hljs-decorator,
114 | .hljs-template_comment,
115 | .hljs-pi,
116 | .hljs-deletion,
117 | .hljs-shebang,
118 | .apache .hljs-sqbracket,
119 | .tex .hljs-formula {
120 | color: #818E96;
121 | }
122 |
123 | .hljs-keyword,
124 | .hljs-literal,
125 | .css .hljs-id,
126 | .hljs-phpdoc,
127 | .hljs-title,
128 | .hljs-header,
129 | .haskell .hljs-type,
130 | .vbscript .hljs-built_in,
131 | .sql .hljs-aggregate,
132 | .rsl .hljs-built_in,
133 | .smalltalk .hljs-class,
134 | .diff .hljs-header,
135 | .hljs-chunk,
136 | .hljs-winutils,
137 | .bash .hljs-variable,
138 | .apache .hljs-tag,
139 | .tex .hljs-special,
140 | .hljs-request,
141 | .hljs-at_rule .hljs-keyword,
142 | .hljs-status {
143 | font-weight: bold;
144 | }
145 |
146 | .coffeescript .javascript,
147 | .javascript .xml,
148 | .tex .hljs-formula,
149 | .xml .javascript,
150 | .xml .vbscript,
151 | .xml .css,
152 | .xml .hljs-cdata {
153 | opacity: 0.5;
154 | }
155 |
--------------------------------------------------------------------------------
/assets/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vzaccaria/DynCSS/28411828f1235ed10235e4c62bb4bce7a71a0ec2/assets/img/background.jpg
--------------------------------------------------------------------------------
/assets/img/silhouette_dune_desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vzaccaria/DynCSS/28411828f1235ed10235e4c62bb4bce7a71a0ec2/assets/img/silhouette_dune_desktop.jpg
--------------------------------------------------------------------------------
/assets/index.jade:
--------------------------------------------------------------------------------
1 | mixin fundesc(name, use, description)
2 | .api__element__name #{name}
3 | .api__element__use #{use}
4 | .api__element__command_desc #{description}
5 |
6 | mixin fundesc_transition_to_one
7 | .api__element
8 | +fundesc('@transitionToOne', '@transitionToOne({when: expr, start: val, end: val}, power)',
9 | 'Returns a value that starts at 0, when `expr` is lower than `start`, and approaches 1.0, when `expr` approaches `end`.')
10 |
11 | .api__element__returns
12 | .api__element__returns__element
13 | .api__element__returns__element__value 0
14 | .api__element__returns__element__when`expr` is lower than `start`
15 |
16 | .api__element__returns__element
17 | .api__element__returns__element__value (expr/val)^power
18 | .api__element__returns__element__when`expr` is higher than `start` but lower than `end`
19 |
20 | .api__element__returns__element
21 | .api__element__returns__element__value 1
22 | .api__element__returns__element__when`expr` is higher `end`
23 |
24 | .api__element_example
25 | :markdown
26 | This snippet turns down opacity when scrolling position (`@win-scrollTop`) is
27 | reaching 400px. The transition follows an sqrt law (`power`=.5)
28 |
29 | ```css
30 | .header {
31 | -dyn-opacity: '1-@transitionToOne({when : @win-scrollTop , start: 0, stop: 400 }, .5)';
32 | }
33 | ```
34 | .api__hr
35 |
36 | mixin fundesc_should_appear
37 | .api__element
38 | +fundesc('@shouldAppear', '@shouldAppear({when: expr, isHigherThan: val})',
39 | 'Returns a value that approaches 1.0 when expr approaches val.')
40 |
41 | .api__element__returns
42 | .api__element__returns__element
43 | .api__element__returns__element__value 0
44 | .api__element__returns__element__when`expr` is lower than 0
45 |
46 | .api__element__returns__element
47 | .api__element__returns__element__value expr/val
48 | .api__element__returns__element__when`expr` is higher than 0 but lower than `val`
49 |
50 | .api__element__returns__element
51 | .api__element__returns__element__value 1
52 | .api__element__returns__element__when`expr` is higher `val`
53 |
54 | .api__element_example
55 | :markdown
56 | This snippet turns up element visibility when scrolling position (`@win-scrollTop`) is
57 | reaching a half of the window's height:
58 |
59 | ```css
60 | .header {
61 | -dyn-opacity: '@shouldAppear({when: @win-scrollTop, isHigherThan: @win-height/2})';
62 | }
63 | ```
64 | .api__element_variations
65 | :markdown
66 | Use `isLowerThan` instead of `isHigherThan` to make elements appear on scroll up.
67 | .api__hr
68 |
69 | mixin fundesc_should_disappear
70 | .api__element
71 | +fundesc('@shouldDisappear', '@shouldDisappear({when: expr, isHigherThan: val})', 'Returns a value that approaches 0.0 when expr approaches val.')
72 |
73 | .api__element__returns
74 | .api__element__returns__element
75 | .api__element__returns__element__value 1
76 | .api__element__returns__element__when`expr` is lower than 0
77 |
78 | .api__element__returns__element
79 | .api__element__returns__element__value 1 - (expr/val)
80 | .api__element__returns__element__when`expr` is higher than 0 but lower than `val`
81 |
82 | .api__element__returns__element
83 | .api__element__returns__element__value 0
84 | .api__element__returns__element__when`expr` is higher `val`
85 |
86 | .api__element_example
87 | :markdown
88 | This snippet turns down opacity when scrolling position (`@win-scrollTop`) is
89 | reaching a fourth of the window's height:
90 |
91 | ```css
92 | .header {
93 | -dyn-opacity: '@shouldDisappear({when: @win-scrollTop, isHigherThan: @win-height/4})';
94 | }
95 | ```
96 | .api__element_variations
97 | :markdown
98 | Use `isLowerThan` instead of `isHigherThan` to make elements disappear on scroll up.
99 | .api__hr
100 |
101 | mixin fundesc_select_from
102 | .api__element
103 | +fundesc('@selectFrom', '@selectFrom(array)', 'Returns the element of `array` associated with the currently active breakpoint (i.e., the one with the same index).')
104 |
105 | .api__element_example
106 | :markdown
107 | Here, we set the font size to 3em under the first breakpoint, 4em under the second, and 5em above the second.
108 |
109 | ```css
110 | .header__title {
111 | -dyn-font-size: '@selectFrom(["3em", "4em", "5em"])';
112 | }
113 | ```
114 |
115 | Breakpoints should be set in Javascript by using the appropriate `setBreakpoints` method:
116 |
117 |
118 | ```html
119 |
122 | ```
123 |
124 | sets two breakpoints at window's width (`@win-width`) equal to 320 and 480 pixels.
125 |
126 | mixin fundesc_if
127 | .api__element
128 | +fundesc('@if', '@if(condition, v1, v2)', 'Returns v1 if condition is true, v2 otherwise.')
129 |
130 | .api__element_example
131 | :markdown
132 | Here, we remove the element when scroll-top is higher than its bottom.
133 |
134 | ```css
135 | .element-to-be-removed {
136 | -dyn-display: '@if(@win-scrollTop > @jq-offset.bottom, "none", "block")';
137 | }
138 | ```
139 |
140 | mixin fundesc_morph
141 | .api__element
142 | +fundesc('@morph', '@morph(factor, v1, v2)', 'Returns the convex combination (1-factor)*v1 + factor*v2.')
143 |
144 | .api__element_example
145 | :markdown
146 | `factor` can be the state of a transition. This snippet resizes the width of `.element` by using the state
147 | returned by `@transitionToOne`.
148 |
149 | ```css
150 | .element {
151 | -dyn-width: '@morph(transitionToOne(...), 200, 300)';
152 | }
153 | ```
154 |
155 |
156 | doctype html
157 | html
158 | head(lang="en")
159 | title DynCSS - Simple dynamic CSS rules to give life to your sites.
160 | meta(http-equiv="content-type", content="text/html, charset=UTF-8")
161 | meta(name="description", content="")
162 | meta(name="keywords", content="")
163 | meta(name="viewport", content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0")
164 | // if lt IE 9
165 | script(type="text/javascript", src="js/html5shiv.js")
166 | link(href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css", rel="stylesheet")
167 | link(rel="stylesheet", href="css/client.css", type="text/css")
168 | link(rel="stylesheet", href="css/vendor.css", type="text/css")
169 | body(style='opacity: 0;')
170 | //- BEM Rules.
171 | .overlay
172 |
173 | .toc
174 | .toc__section.toc__section--what_is_it(onclick="location.href='#what-is-it';", style="cursor: pointer;") What is it
175 | .toc__section.toc__section--features(onclick="location.href='#features';", style="cursor: pointer;") Features
176 | .toc__section.toc__section--responsiveness(onclick="location.href='#responsiveness';", style="cursor: pointer;") Responsiveness
177 | .toc__section.toc__section--dynamic-styles(onclick="location.href='#dynamic-styles';", style="cursor: pointer;") Dynamic styles
178 | .toc__section.toc__section--api(onclick="location.href='#api';", style="cursor: pointer;") API
179 |
180 | .header
181 | .header__title
182 | strong Dyn
183 | |CSS
184 | .header__sub-title Simple, dynamic CSS rules to give life to your sites.
185 |
186 | .header__buttons
187 | a.header__button(onclick="location.href='https://github.com/vzaccaria/DynCSS'", style="cursor: pointer") Github
188 | a.header__button(onclick="location.href='#api';", style="cursor: pointer") Docs
189 | a.header__button(onclick="location.href='http://www.vittoriozaccaria.net/dyncss-example'", style="cursor: pointer") Example
190 |
191 | .sub-header
192 | .sub-header__actions
193 |
194 | .sub-header__action
195 | i.sub-header__action__icon.fa.fa-cloud-download
196 | .sub-header__action__text Install
197 | .sub-header__action__desc
198 | :markdown
199 | ```shell
200 | $ bower install dyn-css
201 | ```
202 |
203 | .sub-header__action
204 | i.sub-header__action__icon.fa.fa-html5
205 | .sub-header__action__text Include
206 | .sub-header__action__desc
207 | :markdown
208 | ```html
209 | ...
210 |
212 | ...
213 | ```
214 |
215 | Less than 20K, uncompressed and unminified. Requires only jQuery.
216 |
217 |
218 | .sub-header__action
219 | i.sub-header__action__icon.fa.fa-gamepad
220 | .sub-header__action__text Enjoy
221 | .sub-header__action__desc
222 | :markdown
223 | ```css
224 | i.fa.fa-gamepad {
225 | -dyn-webkit-transform:
226 | '"rotate(\#{@win-scrollTop}deg) "';
227 | }
228 | ```
229 |
230 | .sub-header__container
231 | hr.sub-header__container__separator
232 |
233 | #what-is-it.sub-header__container__short_desc
234 | :markdown
235 | # What is it?
236 |
237 | DynCSS parses your CSS for `-dyn-(attribute)` rules. These
238 | rules are Javascript expressions evaluated on browser's events like `scroll` and
239 | `resize`. The result is applied to the CSS attribute you have specified as suffix.
240 |
241 | For example, this will
242 | center vertically `.header`, dynamically changing `margin-top` as
243 | the window is resized:
244 |
245 | ```css
246 | .header {
247 | -dyn-margin-top: '(@win-height - @el-height)/2.0';
248 | }
249 | ```
250 |
251 | Here, `@win-height` is the dynamic height of the window and
252 | `@el-height` is the dynamic height of the current element (`.header` in this case). The
253 | header of this page has been centered in this way.
254 |
255 | You can even create parallax effects by using the window's `scrollTop` and dynamically
256 | applying a CSS transform:
257 |
258 | ```css
259 | .header {
260 | -dyn-webkit-transform: '"translate( 0px , \#{-1*@win-scrollTop}px) "';
261 | }
262 | ```
263 |
264 | Since the `webkit-transform` value is a string, the above snippet creates one
265 | by interpolating the dynamic value with `\#{..}`.
266 |
267 | #features.sub-header__container__short_desc
268 | :markdown
269 |
270 | # Features
271 |
272 | You can make dynamic any CSS property — provided that it is writable
273 | by jQuery's `.css()` method. You do this by appending the `-dyn-` prefix and specifying
274 | a quoted Javascript expression.
275 |
276 | You can use placeholders to access dynamic information about the document;
277 | here's a list of built-in placeholders you can use:
278 |
279 | | Prefixes | Description |
280 | |---|---|
281 | | `@win-foo` | dynamically evaluates `window.foo()`|
282 | | `@el-foo` | dynamically evaluates `$(current-selector).css(foo)` |
283 | | `@jq-foo` | dynamically evaluates `$(current-selector).foo()` |
284 |
285 | The syntax should be parsable by any CSS preprocessor. For
286 | example, I am using it with `lessc` for this website.
287 |
288 | # Custom functions
289 | You can introduce custom functions to be evaluated at run-time, by
290 | adding them to `window.dynCss.lib`. For example, here's how you can introduce
291 | a center function that returns the centers of the current window:
292 |
293 | ```css
294 | window.dynCss.lib.center = function() {
295 | return {x: window.width()/2, y: window.height()/2 };
296 | }
297 | ```
298 |
299 | To use it in a rule, invoke it with the `@` prefix:
300 |
301 | ```css
302 | -dyn-margin-left: '@center().x';
303 | ```
304 |
305 | ## Virtual properties - new
306 |
307 | To enable more precise positioning of elements, the following dynamic properties
308 | of position=fixed elements have been introduced:
309 |
310 | | property name | affects |
311 | | ------------- | --------|
312 | | -dyn-fixed-vertical-center | top |
313 | | -dyn-fixed-horizontal-center | left |
314 |
315 | They take implicitly into account the size of the element in order to center it
316 | horizontally; for example:
317 |
318 | ```css
319 | .element {
320 | position: fixed;
321 | -dyn-fixed-vertical-center: '@fixedVerticalCenter(".element2")';
322 | }
323 | ```
324 | will vertically align `.element` to `.element2` (another fixed element).
325 |
326 |
327 | #responsiveness.sub-header__container__short_desc
328 | :markdown
329 |
330 | # Responsiveness
331 | DynCSS allows to easily program responsiveness in your CSS.
332 | To do so you define a list of breakpoints and
333 | the dynamic variable to watch (which is typically the size of the window). You can do this in a `
341 | ```
342 |
343 | Now, you can define how each property behaves above an below the breakpoints;
344 | for example, we can change dynamically the font size:
345 |
346 | ```css
347 | .header__title {
348 | -dyn-font-size: '@selectFrom(["3em", "4em", "5em"])';
349 | }
350 | ```
351 |
352 | `selectFrom` is a built-in function that returns one of the elements of the input list
353 | by using the breakpoints specified with `setBreakpoints`.
354 | Here, the font size will be 3em under 480px, 4em under 960px, and 5em above 960px.
355 |
356 | #dynamic-styles.sub-header__container__short_desc
357 | :markdown
358 |
359 | # Dynamic styles
360 | DynCSS allows to add a class dynamically to all elements of a given selector, based on
361 | a condition to be evaluated at run-time; this is useful to build scroll spies.
362 | You can specify the class name to be added with `-dyn-set-state-(class-name)`:
363 |
364 | ```css
365 | .to-be-highlighted {
366 | -dyn-set-state-highlight: '@isVerticallyVisible("#my-section")';
367 | }
368 |
369 | ```
370 | here, we add a `.highlight` class to all elements `.to-be-highlighted` whenever the function
371 | `@isVerticallyVisible` returns true. We assume that `isVerticallyVisible` receives a selector
372 | and checks whether it is in or out of the view port.
373 |
374 | Here's a custom definition of `isVerticallyVisible` in Livescript, but you can write your own of course:
375 |
376 | ```livescript
377 |
378 | isVerticallyVisible = (el, threshold) ->
379 | r = jQuery(el)[0].getBoundingClientRect();
380 | w = jQuery(window)
381 | vp = {}
382 | vp.top = w.scrollTop()
383 | vp.bottom = w.scrollTop() + w.height()
384 | if not threshold?
385 | threshold := w.height()/3
386 | value =
387 | | r.top >= 0 and r.top < (threshold) => true
388 | | r.top < 0 and r.bottom > (threshold) => true
389 | | otherwise => false
390 |
391 | return value
392 |
393 | ```
394 |
395 |
396 |
397 | #api.sub-header__container__short_desc
398 |
399 |
400 |
401 | :markdown
402 |
403 | # API
404 |
405 | Here are some built-in functions you can use in your `-dyn-*` rules:
406 |
407 | .sub-header__short_desc__api
408 | +fundesc_should_appear()
409 | +fundesc_should_disappear()
410 | +fundesc_select_from()
411 | +fundesc_transition_to_one()
412 | +fundesc_if()
413 | +fundesc_morph()
414 |
415 |
416 |
417 | .sub-header__footer
418 | .sub-header__footer__container
419 | .sub-header__footer__madeby
420 | a.sub-header__footer__madeby__name_lastname(href='http://www.vittoriozaccaria.net') Vittorio Zaccaria
421 |
422 |
423 | a.sub-header__footer__license BSD
424 | .sub-header__footer__share
425 | #here-reddit.sub-header__footer__share__reddit
426 |
427 | .sub-header__footer__share__twitter
428 | a#here-twitter(href="https://twitter.com/share",class="twitter-share-button",data-count='vertical', data-via="_vzaccaria_") Tweet
429 |
430 |
431 |
432 | script(type="text/javascript", src="js/vendor.js")
433 | script(type="text/javascript", src="js/client.js")
434 |
435 | script.
436 | window.dynCss.api.setBreakpoints([481,961],'@win-width');
437 |
438 | script(src='//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.0/highlight.min.js')
439 | script.
440 | hljs.initHighlightingOnLoad();
441 |
442 |
443 |
444 | // if IE
445 | script(type="text/javascript", src="js/placeholder.js")
--------------------------------------------------------------------------------
/assets/js/core.ls:
--------------------------------------------------------------------------------
1 | built-in = require('./lib')
2 |
3 | blue = '#3498db'
4 | red = '#c0392b'
5 | normal = 'black'
6 |
7 | core-debug-message = (m) ->
8 | if window.dynCss.config.debug
9 | console.log "%cdyncss-core : %c#m", "color: #blue", "color: #normal"
10 |
11 | core-heavy-debug-message = (m) ->
12 | if window.dynCss.config.debug
13 | console.log "%cdyncss-core : %c#m", "color: #red", "color: #normal"
14 |
15 | dyn-css = (window-di, document-di, jq-di) ->
16 |
17 | inner-module = ->
18 | # Use `inner-module` to inject dependencies into `dep`
19 | # e.g. sinon.stub mod.inner-module().dep, 'method'.
20 | #
21 | # You can access `dep` method with plain `dep.method`
22 | # in functions defined below.
23 | return this
24 |
25 |
26 | window-di.dynCss = {}
27 | window-di.dynCss.lib = built-in
28 | window-di.dynCss.data = {}
29 | window-di.dynCss.config =
30 | debug: false
31 | dontComputeInvisible: false
32 | useRAF: false;
33 |
34 |
35 | # __ __ _ __
36 | # / /_ ________ ____ _/ /______ ____ (_)___ / /______
37 | # / __ \/ ___/ _ \/ __ `/ //_/ __ \/ __ \/ / __ \/ __/ ___/
38 | # / /_/ / / / __/ /_/ / ,< / /_/ / /_/ / / / / / /_(__ )
39 | # /_.___/_/ \___/\__,_/_/|_/ .___/\____/_/_/ /_/\__/____/
40 | # /_/
41 |
42 | class breakpoint
43 |
44 | (@name, @breakpoints, @expression) ->
45 | @expression = transcompile-function @expression
46 | @compiled = window-di.dynCss.api.create-function @expression
47 |
48 | set-named-breakpoints = (name, list, expression) ->
49 | window-di.dynCss.data[name] = new breakpoint(name, list, expression)
50 |
51 | set-breakpoints = (list, variable) ->
52 | set-named-breakpoints 'responsive', list, variable
53 |
54 | window-di.dynCss.api = {
55 | set-breakpoints: set-breakpoints
56 | set-named-breakpoints: set-named-breakpoints
57 |
58 | force-redraw: ->
59 | ss = document.styleSheets[0];
60 | try
61 | ss.addRule('.xxxxxx', 'position: relative');
62 | catch
63 |
64 | force-redraw-brute: ->
65 | $(window).hide().show()
66 | }
67 |
68 |
69 |
70 | #
71 | # _________ ________
72 | # / ___/ __ \/ ___/ _ \
73 | # / /__/ /_/ / / / __/
74 | # \___/\____/_/ \___/
75 | #
76 |
77 | camelize = (str) ->
78 | ex = /[-_\s]+(.)?/g
79 | return str.replace ex, (m, c) ->
80 | | c? => c.toUpperCase()
81 | | otherwise => ""
82 |
83 |
84 | get-scroll-expression = (d) ->
85 | if (results = d.property is /\-dyn\-(.*)/)?
86 | property = results[1]
87 | if (results = d.value is /'(.*)'/)?
88 | expression = results[1]
89 |
90 | if property == 'fixed-right-edge'
91 |
92 | property = 'left'
93 | expression = "#expression - @el-width"
94 |
95 | if property == 'fixed-left-edge'
96 |
97 | property = 'left'
98 | expression = "#expression"
99 |
100 | if property == 'fixed-bottom-edge'
101 |
102 | property = 'top'
103 | expression = "#expression - @el-height"
104 |
105 | if property == 'fixed-top-edge'
106 |
107 | property = 'top'
108 | expression = "#expression"
109 |
110 | if property == 'fixed-horizontal-center'
111 |
112 | property = 'left'
113 | expression = "#expression - @el-width/2"
114 |
115 | if property == 'fixed-vertical-center'
116 |
117 | property = 'top'
118 | expression = "#expression - @el-height/2"
119 |
120 | return { property: property, expression: expression }
121 | return undefined
122 |
123 | transcompile-function = (body) ->
124 | core-debug-message body if window-di.dynCss.config.debug
125 | body = body.replace(/@a-(\w+){(.+)}/g , 'this.lib.jqRef(\'$2\').$1()')
126 | body = body.replace(/\#{(.+)}/g , '"+($1)+"')
127 | body = body.replace(/@i-(\w+)/g , 'parseInt(this.el.css(\'$1\'))')
128 | body = body.replace(/@j-(\w+)/g , 'this.lib.jqRef(this.el).$1()')
129 | body = body.replace(/@w-(\w+)/g , '(this.lib.wRef.$1())')
130 | body = body.replace(/@el-(\w+)/g , 'parseInt(this.el.css(\'$1\'))')
131 | body = body.replace(/@jq-(\w+)/g , 'this.lib.jqRef(this.el).$1()')
132 | body = body.replace(/@win-(\w+)/g , '(this.lib.wRef.$1())')
133 | body = body.replace(/@/g , 'this.lib.')
134 | return body
135 |
136 | window-di.dynCss.api.create-function = (body) ->
137 |
138 | script = document-di.createElement("script")
139 | script.text = "window.tmp = function() { return (#body); }.bind(window.dynCss);"
140 |
141 | document-di.head.appendChild( script ).parentNode.removeChild( script );
142 | return window-di.tmp
143 |
144 |
145 | build-handlers = (rules, refresh-handler) ->
146 |
147 | window-di.dynCss.lib.jqRef = jq-di
148 | window-di.dynCss.lib.wRef = jq-di(window-di)
149 |
150 |
151 | for rule in rules
152 | if rule.type is "rule"
153 | sel = rule.selectors
154 |
155 | actions = []
156 |
157 | for decl in rule.declarations
158 | result = get-scroll-expression(decl)
159 | if result?
160 |
161 | { property, expression, trigger} = result
162 | comp = transcompile-function expression
163 | handler = window-di.dynCss.api.create-function comp
164 | actions.push { property: camelize(property), original-property: property, funct: handler, sel: sel }
165 |
166 | wrapper = (next) ->
167 | let act = actions, scoped-sel=sel
168 | (changed) ->
169 | for sct in scoped-sel
170 | jq-di(sct).each (i) ->
171 | window-di.dynCss.el = jq-di(this)
172 | css = {}
173 | for a in act
174 | if (r = (a.original-property == /set-state-(.+)/))
175 | cc = r[1]
176 | if a.funct()
177 | window-di.dynCss.el.addClass(cc)
178 | else
179 | window-di.dynCss.el.removeClass(cc)
180 | else
181 | core-debug-message "Assigning to #{sct}.#{a.property} value #{a.funct()}" if window-di.dynCss.config.debug
182 | css[a.property] = a.funct()
183 |
184 |
185 | for k,v of css
186 | is-initial-phase = (not this.old-value?) or (not this.old-value?[k]?)
187 | is-changed = (this.old-value? and this.old-value[k]? and css[k] != this.old-value[k])
188 | # is-not-hidden = (css['display']?) and not (css['display']='hidden')
189 | is-not-hidden =
190 | | not window-di.dynCss.config.dontComputeInvisible => true
191 | | window-di.dynCss.el.css('display') != 'none' => true
192 | | otherwise => false
193 |
194 | is-visibility-toggled = (k == 'display')
195 | if (is-initial-phase and is-not-hidden) or (is-changed and is-not-hidden) or (is-changed and is-visibility-toggled)
196 | core-heavy-debug-message "#sct - #k transition (#{this.old-value?[k]} --> #{css[k]})" if window-di.dynCss.config.debug
197 | window-di.dynCss.el.css({"#k": v})
198 | this.old-value ?= {}
199 | this.old-value[k] = v
200 | changed := true
201 |
202 | new-value = JSON.stringify(css)
203 |
204 | next(changed) if next?
205 |
206 | if actions.length != 0
207 | refresh-handler := wrapper(refresh-handler)
208 |
209 | return refresh-handler
210 |
211 | return {
212 | inner-module: inner-module
213 | build-handlers: build-handlers
214 | }
215 |
216 | module.exports = dyn-css
217 |
--------------------------------------------------------------------------------
/assets/js/entry.ls:
--------------------------------------------------------------------------------
1 |
2 | css-parse = require('css-parse')
3 | built-in = require('./lib')
4 | dyn-css = require('./core')
5 | _q = require('q')
6 |
7 | { build-handlers } = dyn-css(window, document, jQuery)
8 |
9 | # __ ____
10 | # / /_ ____ _____ ____/ / /__ __________
11 | # / __ \/ __ `/ __ \/ __ / / _ \/ ___/ ___/
12 | # / / / / /_/ / / / / /_/ / / __/ / (__ )
13 | # /_/ /_/\__,_/_/ /_/\__,_/_/\___/_/ /____/
14 | #
15 |
16 | blue = '#3498db'
17 | red = '#c0392b'
18 | normal = 'black'
19 |
20 | entry-debug-message = (m) ->
21 | if window.dynCss.config.debug
22 | console.log "%cdyncss-entry: %c#m", "color: #blue", "color: #normal"
23 |
24 | var scroll-handler
25 |
26 | refresh-handler = (changed) ->
27 | if changed
28 | window.dynCss.api.force-redraw()
29 |
30 | decimate = 1
31 | iOS = /(iPad|iPhone|iPod)/g.test( navigator.userAgent );
32 | counter = 0
33 | lt = 0
34 | fixed-ttc = (1000/1)
35 |
36 | install-custom-raf = ->
37 | window.custom-request-animation-frame = (cb) ->
38 | ct = new Date().getTime()
39 | ttc = Math.max(0, 16 - (ct - lt))
40 | if fixed-ttc?
41 | set-timeout cb, fixed-ttc, true
42 | else
43 | set-timeout cb, ttc, true
44 |
45 | lt := ct + ttc
46 |
47 | install-scroll-handler = (options) ->
48 | scroll-handler := ->
49 | if window.dynCss.config.useRAF
50 | window.request-animation-frame ->
51 | if (counter % decimate) == 0
52 | refresh-handler(false)
53 | counter := counter + 1
54 | else
55 | if (counter % decimate) == 0
56 | refresh-handler(false)
57 | counter := counter + 1
58 |
59 | if options?.only-on-resize?
60 | window.onresize = scroll-handler
61 | else
62 | if not options?.only-on-start?
63 | window.onscroll = scroll-handler
64 | window.ontouchmove = scroll-handler
65 | window.onresize = scroll-handler
66 |
67 | # _ __
68 | # ____ ___ ____ _(_)___ ___ ____ / /________ __
69 | # / __ `__ \/ __ `/ / __ \ / _ \/ __ \/ __/ ___/ / / /
70 | # / / / / / / /_/ / / / / / / __/ / / / /_/ / / /_/ /
71 | # /_/ /_/ /_/\__,_/_/_/ /_/ \___/_/ /_/\__/_/ \__, /
72 | # /____/
73 |
74 | entry-debug-message "Scanning for css"
75 |
76 | parse-css = (n) ->
77 | entry-debug-message "Loading #{n.href}"
78 | _d = _q.defer()
79 | if n.href?
80 | $.get n.href, ->
81 | entry-debug-message "Loaded #{n.href}"
82 | rules = css-parse(it).stylesheet.rules
83 | refresh-handler := build-handlers(rules, refresh-handler)
84 | if refresh-handler?
85 | if iOS
86 | install-scroll-handler({+only-on-start})
87 | else
88 | install-scroll-handler()
89 | _d.resolve()
90 | return _d.promise
91 |
92 | _loaded_d = _q.defer()
93 | _loaded_p = _loaded_d.promise
94 |
95 | window.onload = ->
96 | entry-debug-message "Content loaded"
97 | _loaded_d.resolve()
98 |
99 | $(document).ready = ->
100 | entry-debug-message "Document parsed."
101 |
102 | results = $('link[type="text/css"]')
103 | p-array = [ parse-css(r) for r in results ] ++ [ _loaded_p ]
104 |
105 | _q.all(p-array).then ->
106 | entry-debug-message "Initializing handler"
107 | scroll-handler()
108 |
109 | window.dynCss.api.initVariable = (vr, value) ->
110 | window.dynCss.lib[vr] = value
111 |
112 | window.dynCss.api.setVariable = (vr, value) ->
113 | window.dynCss.api.initVariable vr, value
114 | scroll-handler()
115 |
116 | window.dynCss.api.initToggle = (vr, value1, value2) ->
117 | window.dynCss.api.initVariable vr, value1
118 | window.dynCss.api.initVariable vr+"Value0", value1
119 | window.dynCss.api.initVariable vr+"Value1", value2
120 | entry-debug-message "Initialising variable #vr to #value1"
121 |
122 | window.dynCss.api.toggle = (vr) ->
123 | vv = window.dynCss.lib[vr]
124 | v1 = window.dynCss.lib[vr+"Value0"]
125 | v2 = window.dynCss.lib[vr+"Value1"]
126 | if vv == v1
127 | window.dynCss.api.setVariable vr, v2
128 | entry-debug-message "Setting #vr to #v2"
129 | else
130 | window.dynCss.api.setVariable vr, v1
131 | entry-debug-message "Setting #vr to #v1"
132 |
--------------------------------------------------------------------------------
/assets/js/lib.ls:
--------------------------------------------------------------------------------
1 |
2 | const debug = false
3 |
4 | perspective = (px) ->
5 | return "perspective(#{px}px) "
6 |
7 | sat = (x) ->
8 | | x>1 => 1
9 | | x<0 => 0
10 | | otherwise => x
11 |
12 | as-percentage-of = (/)
13 |
14 | as-remaining-percentage-of = (x, y) ->
15 | 1 - x `as-percentage-of` y
16 |
17 | shouldDisappear = (context) ->
18 | { is-higher-than, is-lower-than, when: wn } = context
19 | if is-higher-than? and wn?
20 | return sat(wn `as-remaining-percentage-of` is-higher-than)
21 |
22 | if is-lower-than? and wn?
23 | v = sat(wn `as-percentage-of` is-lower-than)
24 | return v
25 |
26 | transitionToOne = (context, power = 1) ->
27 | var int, vv, direction
28 |
29 | { start, stop, when: val } = context
30 | orig = val
31 |
32 | pp =
33 | | start 0
34 | | startstop => 1
35 | | start (val - start) / (stop - start)
36 | | start>stop and val>start => 1
37 | | start>stop and val 0
38 | | start>stop => 1 - (val - stop) / (start - stop)
39 |
40 | vv = sat(pp)
41 | return vv ** power
42 |
43 |
44 | shouldAppear = (context) ->
45 | { is-higher-than, is-lower-than, when: wn } = context
46 | wn = context['when']
47 | var vv, int
48 |
49 | if is-higher-than? and wn?
50 | int := wn `as-percentage-of` is-higher-than
51 |
52 | if is-lower-than? and wn?
53 | int := wn `as-remaining-percentage-of` is-lower-than
54 |
55 | vv := sat(int)
56 | console.log "final: #vv, intermediate: #int, is-higher: #is-higher-than, is-lower: #is-lower-than" if debug
57 |
58 | return vv
59 |
60 | selectFrom = (values) ->
61 | dt = window.dynCss.data['responsive']
62 | try
63 | if dt.compiled? and values.length > 0
64 | vv = dt.compiled()
65 | for b,i in dt.breakpoints
66 |
67 | if vv < b or (i == (values.length - 1))
68 | return values[i]
69 |
70 | return values[* - 1]
71 | catch error
72 |
73 | ifThenElse = (cond, v1, v2) ->
74 | if cond
75 | v1
76 | else
77 | v2
78 |
79 | isVerticallyVisible = (el, threshold) ->
80 |
81 | r = jQuery(el)[0].getBoundingClientRect!
82 | w = jQuery(window)
83 | vp =
84 | top: w.scrollTop!
85 | bottom: w.scrollTop! + w.height!
86 |
87 | threshold ?= w.height! / 3
88 |
89 |
90 | value =
91 | | r.top >= 0 and r.top < threshold => true
92 | | r.top < 0 and r.bottom > threshold => true
93 | | otherwise => false
94 |
95 | return value
96 |
97 |
98 | # These work only on fixed position elements
99 |
100 | top-of = (el) ->
101 | if el != window
102 | jQuery(el).offset!top - $(window).scrollTop!
103 | else
104 | 0
105 |
106 | bottom-of = (el) ->
107 | if el != window
108 | jQuery(el).offset!top - $(window).scrollTop! + parseInt(jQuery(el).css('margin-bottom')) + jQuery(el).innerHeight!
109 | else
110 | $(window).height!
111 |
112 | left-of = (el) ->
113 | if el != window
114 | jQuery(el).offset!.left + parseInt(jQuery(el).css('margin-right'))
115 | else
116 | 0
117 |
118 | right-of = (el) ->
119 | if el != window
120 | jQuery(el).offset!.left + parseInt(jQuery(el).css('margin-right')) + jQuery(el).innerWidth()
121 | else
122 | $(window).width!
123 | # jQuery(el).offset().left + parseInt(jQuery(el).css('margin-left')) + jQuery(el).innerWidth()
124 |
125 |
126 |
127 | _module = ->
128 |
129 |
130 | iface =
131 | shouldDisappear : shouldDisappear
132 | convergeToZero : shouldDisappear
133 | shouldAppear : shouldAppear
134 | convergeToOne : shouldAppear
135 |
136 | transitionToOne : transitionToOne
137 |
138 | perspective : perspective
139 | selectFrom : selectFrom
140 | isVerticallyVisible : isVerticallyVisible
141 | if : ifThenElse
142 |
143 | fixed-top-edge : top-of
144 | fixed-bottom-edge : bottom-of
145 | fixed-right-edge : right-of
146 | fixed-left-edge : left-of
147 |
148 | pos: (el) -> # could be (.offset) . ($)
149 | $(el).offset!
150 |
151 |
152 | fixed-horizontal-center: ->
153 | (right-of(it) + left-of(it)) / 2
154 |
155 | fixed-vertical-center: ->
156 | (top-of(it) + bottom-of(it)) / 2
157 |
158 | morph: (c, v1, v2) ->
159 | vv = v1*(1-c) + v2*c
160 | return vv
161 |
162 |
163 | should-be-visible: ->
164 | $w-top = $(window).scrollTop!
165 | $el = jQuery(window.dynCss.el)
166 | $el-top = $el.offset!top
167 | $el-h = $el.innerHeight!
168 | $w-height = $(window).height!
169 | $set-off = $el-top
170 | v = shouldAppear(when: $(window).scrollTop!, is-higher-than: $set-off)
171 |
172 | console.log "top = #{$w-top}, completed-at = #{$set-off}, visible = #v, eltop = #{$el-top}, el-h = #{$el-h}" if debug
173 | return v
174 |
175 |
176 | return iface
177 |
178 | module.exports = _module()
179 |
--------------------------------------------------------------------------------
/assets/js/site.ls:
--------------------------------------------------------------------------------
1 |
2 | # Apply it to the div that will contain the widget:
3 | #
4 | # #here-reddit.sub-header__footer__share__reddit
5 |
6 |
7 | add-reddit-button = (selector) ->
8 | thisurl = encodeURIComponent(window.location.href);
9 | url = "http://www.reddit.com/static/button/button2.html?width=51&url=#thisurl"
10 | iframe = ''
11 | $(selector).append(iframe)
12 |
13 |
14 | # Apply it to the a that will contain the widget
15 | # .sub-header__footer__share__twitter
16 | # a#here-twitter(href="https://twitter.com/share",class="twitter-share-button",data-count='vertical', data-via="_vzaccaria_") Tweet
17 |
18 | add-twitter-button = (selector) ->
19 | url = "http://platform.twitter.com/widgets.js"
20 | script = ""
21 | $(selector).before(script)
22 |
23 |
24 | $(document).ready ->
25 | add-reddit-button('#here-reddit')
26 | add-twitter-button('#here-twitter')
27 | $('body').fadeTo(1000, 1.0)
28 |
29 |
--------------------------------------------------------------------------------
/assets/js/test.ls:
--------------------------------------------------------------------------------
1 |
2 |
3 | require! 'should'
4 | require! 'sinon'
5 |
6 | moment = require 'moment'
7 | __q = require('q')
8 |
9 | notifies-on-fail = (p, cb) ->
10 | p.then((-> cb(it)),(-> cb()))
11 |
12 | notifies-on-success = (p, cb) ->
13 | p.then((-> cb()), (-> cb(it)))
14 |
15 | create-resolved-promise = ->
16 | d = __q.defer()
17 | p = d.promise
18 | d.resolve()
19 | return p
20 |
21 | create-rejected-promise = ->
22 | d = __q.defer()
23 | p = d.promise
24 | d.reject()
25 | return p
26 |
27 | var dyncss
28 |
29 | var window-di
30 | var jq-di
31 | var el-di
32 | var document-di
33 | var temp-stub1
34 | var rules
35 | var iterator
36 |
37 | quote = (i) -> "\'#i\'"
38 |
39 | describe 'DynCSS tests - base', (empty) ->
40 | before-each ->
41 |
42 | dyncss := require('./core')
43 |
44 | window-di := { type: "window" }
45 |
46 | document-di := { type: "document" }
47 |
48 | el-di := {
49 | type: "element"
50 | css: (css) ->
51 |
52 | }
53 |
54 | iterator := {
55 | each: (cb) ->
56 | cb.apply(el-di, [0])
57 | }
58 |
59 | # That's a short jquery hack..
60 | jq-di := (sel) ->
61 |
62 | if not sel.type? and sel == '.test'
63 | return iterator
64 |
65 | if sel.type == "window"
66 | return window-di
67 |
68 | if sel.type == "element"
69 | return el-di
70 |
71 | dyncss := dyncss(window-di, document-di , jq-di)
72 |
73 | window-di.width = -> 100
74 | window-di.height = -> 100
75 |
76 | # sinon.stub window-di, 'height', -> 200
77 |
78 | rules := [
79 |
80 | * type: 'rule'
81 | selectors: ['.test']
82 | declarations: [
83 | * property: '-dyn-width'
84 | value: quote(333)
85 | ]
86 |
87 | ]
88 |
89 | temp-stub1 := sinon.stub window-di.dynCss.api, 'createFunction', (body) ->
90 | (-> eval(body)).bind(window-di.dynCss)
91 |
92 | after-each ->
93 | temp-stub1.restore()
94 |
95 |
96 |
97 | it 'should instantiate correctly main module', ->
98 | should.exist(dyncss)
99 |
100 | it 'should instantiate internal data structures', ->
101 | should.exist(window-di.dynCss.data)
102 |
103 | it 'should instantiate breakpoint api', ->
104 | should.exist(window-di.dynCss.api.set-breakpoints)
105 |
106 | it 'should access inner module functions', ->
107 | should.exist(window-di.dynCss.api.create-function)
108 |
109 | it 'should stub correctly create a function', ->
110 | f = window-di.dynCss.api.create-function('3')
111 | f.should.be.a.Function
112 | f().should.be.exactly(3)
113 |
114 | it 'should create a simple rule', ->
115 | handler = dyncss.build-handlers(rules, undefined)
116 | should.exist(handler)
117 | handler.should.be.a.Function
118 |
119 | it 'should modify the css when created', ->
120 | handler = dyncss.build-handlers(rules, undefined)
121 | cssspy = sinon.spy(el-di, 'css')
122 | handler()
123 | cssspy.callCount.should.be.exactly(1)
124 | should.exist(cssspy.firstCall.args[0].width)
125 | cssspy.firstCall.args[0].width.should.be.exactly(333)
126 | cssspy.restore()
127 |
128 | describe 'DynCSS tests - using built-in', (empty) ->
129 | before-each ->
130 |
131 | dyncss := require('./core')
132 |
133 | window-di := { type: "window" }
134 |
135 | document-di := { type: "document" }
136 |
137 | el-di := {
138 | type: "element"
139 |
140 | css: (css) ->
141 | if css == "size"
142 | return '444'
143 |
144 | width: ->
145 | 222
146 | }
147 |
148 | iterator := {
149 | each: (cb) ->
150 | cb.apply(el-di, [0])
151 | }
152 |
153 | # That's a short jquery hack..
154 | jq-di := (sel) ->
155 |
156 | if not sel.type? and sel == '.test'
157 | return iterator
158 |
159 | if sel.type == "window"
160 | return window-di
161 |
162 | if sel.type == "element"
163 | return el-di
164 |
165 | dyncss := dyncss(window-di, document-di , jq-di)
166 |
167 | window-di.width = -> 101
168 | window-di.height = -> 100
169 |
170 | # sinon.stub window-di, 'height', -> 200
171 |
172 | rules := [
173 |
174 | * type: 'rule'
175 | selectors: ['.test']
176 | declarations: [
177 | * property: '-dyn-width'
178 | value: quote('@win-width')
179 | ]
180 |
181 | ]
182 |
183 | temp-stub1 := sinon.stub window-di.dynCss.api, 'createFunction', (body) ->
184 | (-> eval(body)).bind(window-di.dynCss)
185 |
186 | after-each ->
187 | temp-stub1.restore()
188 |
189 |
190 | it 'should create a rule accessing the window width', ->
191 | handler = dyncss.build-handlers(rules, undefined)
192 | should.exist(handler)
193 | handler.should.be.a.Function
194 |
195 | it 'should modify the css when created', ->
196 | handler = dyncss.build-handlers(rules, undefined)
197 | cssspy = sinon.spy(el-di, 'css')
198 | handler()
199 | cssspy.callCount.should.be.exactly(1)
200 | should.exist(cssspy.firstCall.args[0].width)
201 | cssspy.firstCall.args[0].width.should.be.exactly(101)
202 |
203 | it 'should create a rule accessing an element jquery computed value', ->
204 |
205 | rules := [
206 |
207 | * type: 'rule'
208 | selectors: ['.test']
209 | declarations: [
210 | * property: '-dyn-width'
211 | value: quote('@jq-width')
212 | ]
213 |
214 | ]
215 |
216 | handler = dyncss.build-handlers(rules, undefined)
217 | should.exist(handler)
218 | handler.should.be.a.Function
219 | cssspy = sinon.spy(el-di, 'css')
220 | handler()
221 | cssspy.callCount.should.be.exactly(1)
222 | should.exist(cssspy.firstCall.args[0].width)
223 | cssspy.firstCall.args[0].width.should.be.exactly(222)
224 | cssspy.restore()
225 |
226 | it 'should create a rule accessing an element css property width', ->
227 |
228 | rules := [
229 |
230 | * type: 'rule'
231 | selectors: ['.test']
232 | declarations: [
233 | * property: '-dyn-width'
234 | value: quote('@el-size')
235 | ]
236 |
237 | ]
238 |
239 | handler = dyncss.build-handlers(rules, undefined)
240 | should.exist(handler)
241 | handler.should.be.a.Function
242 | cssspy = sinon.spy(el-di, 'css')
243 | handler()
244 | cssspy.callCount.should.be.exactly(2)
245 | should.exist(cssspy.secondCall.args[0].width)
246 | cssspy.secondCall.args[0].width.should.be.exactly(444)
247 | cssspy.restore()
248 |
249 |
250 |
251 |
252 |
253 |
--------------------------------------------------------------------------------
/assets/less/main.less:
--------------------------------------------------------------------------------
1 | @import url(http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900);
2 | @import url(http://fonts.googleapis.com/css?family=Inconsolata);
3 |
4 | // _ _ _
5 | // _ ______ ______(_)___ __ _______ ____ ___ (_) __(_)___ _____
6 | // | | / / __ `/ ___/ / __ \/ / / / ___/ / __ `__ \/ / |/_/ / __ \/ ___/
7 | // | |/ / /_/ / / / / /_/ / /_/ (__ ) / / / / / / /> / / / (__ )
8 | // |___/\__,_/_/ /_/\____/\__,_/____/ /_/ /_/ /_/_/_/|_/_/_/ /_/____/
9 | //
10 |
11 | @import "../../vendor/less-elements.less";
12 |
13 |
14 | .smallcaps (@color, @font-weight) {
15 | // depends on the font family.
16 | // some font-families don't support small caps
17 | // or don't provide them with their web font.
18 | font-variant: small-caps;
19 | font-weight: @font-weight;
20 | text-transform: lowercase;
21 | color: @color;
22 | }
23 |
24 |
25 | // __ ___
26 | // _____/ /___ __/ (_)___ ____ _
27 | // / ___/ __/ / / / / / __ \/ __ `/
28 | // (__ ) /_/ /_/ / / / / / / /_/ /
29 | // /____/\__/\__, /_/_/_/ /_/\__, /
30 | // /____/ /____/
31 |
32 |
33 | *:focus {
34 | outline: 0;
35 | }
36 |
37 |
38 | body {
39 | font-family: Lato, Helvetica;
40 | background-color: black;
41 | color: white;
42 | }
43 |
44 | code {
45 | font-family: Inconsolata;
46 | }
47 |
48 |
49 | // __ __
50 | // / /_ ___ ____ _____/ /__ _____
51 | // / __ \/ _ \/ __ `/ __ / _ \/ ___/
52 | // / / / / __/ /_/ / /_/ / __/ /
53 | // /_/ /_/\___/\__,_/\__,_/\___/_/
54 | //
55 |
56 | @disappear-state: '@shouldDisappear({when: @win-scrollTop, isHigherThan: @win-height/4})';
57 |
58 | .header {
59 | width : 70%;
60 | -dyn-transform : '"translate( 0px , #{-1*@win-scrollTop}px) "';
61 | -dyn-margin-top : '(@win-height - @el-height)/2.0';
62 | -dyn-margin-left : '(@win-width - @el-width)/2.0';
63 | -dyn-opacity : @disappear-state;
64 |
65 | }
66 |
67 | .header__title {
68 | -dyn-font-size : '@selectFrom(["3em", "4em", "5em"])';
69 | font-size : 5em;
70 | font-weight : 100;
71 | padding-bottom : .3em;
72 | }
73 |
74 | .header__sub-title {
75 | -dyn-font-weight : '@selectFrom(["300", "100", "100"])';
76 | -dyn-font-size : '@selectFrom(["1em", "1.5em", "2em"])';
77 | font-size : 2em;
78 | padding-bottom : 1.5em;
79 | }
80 |
81 | .header__buttons {
82 | font-size: 1em;
83 | font-weight: 300;
84 | }
85 |
86 | .header__button {
87 | -dyn-font-size : '@selectFrom(["1em", "1.5em", "1.5em"])';
88 | -dyn-display : '@selectFrom(["block", "block", "inline"])';
89 | -dyn-margin-top : '@selectFrom(["1em" , "1em" , "0em"])';
90 | margin-right : 30px;
91 | padding : 10px 30px 10px 30px;
92 | border : solid 1px white;
93 | color : white;
94 | font-size : 1.5em;
95 | }
96 |
97 | // __ __ __
98 | // _______ __/ /_ / /_ ___ ____ _____/ /__ _____
99 | // / ___/ / / / __ \______/ __ \/ _ \/ __ `/ __ / _ \/ ___/
100 | // (__ ) /_/ / /_/ /_____/ / / / __/ /_/ / /_/ / __/ /
101 | // /____/\__,_/_.___/ /_/ /_/\___/\__,_/\__,_/\___/_/
102 | //
103 |
104 | .sub-header {
105 | position : absolute;
106 | -dyn-top : '(@win-height)';
107 | background : white;
108 | width : 100%;
109 | box-sizing : border-box;
110 |
111 | }
112 |
113 |
114 | // Subheader __ _
115 | // ____ ______/ /_(_)___ ____ _____
116 | // / __ `/ ___/ __/ / __ \/ __ \/ ___/
117 | // / /_/ / /__/ /_/ / /_/ / / / (__ )
118 | // \__,_/\___/\__/_/\____/_/ /_/____/
119 | //
120 |
121 | .sub-header__actions {
122 | display : inline-block;
123 | box-sizing : border-box;
124 | padding-top : 5em;
125 | color : darken(white, 90%);
126 | -dyn-width : '@selectFrom(["100%", "80%", "80%"])';
127 | -dyn-margin-left : '@selectFrom(["0" , "10%" , "10%"])';
128 | -dyn-margin-right : '@selectFrom(["0" , "10%" , "10%"])';
129 | }
130 |
131 | .sub-header__action {
132 | box-sizing : border-box;
133 | display : block;
134 | text-align : center;
135 | float : left;
136 | -dyn-width : '@selectFrom(["100%", "100%", "30%"])';
137 | -dyn-margin-left : '@selectFrom(["0px" , "0px" , "15px"])';
138 | -dyn-margin-right : '@selectFrom(["0px" , "0px" , "15px"])';
139 | -dyn-margin-top : '@selectFrom(["5em" , "1em" , "0em"])';
140 | }
141 |
142 | .sub-header__action__icon {
143 | font-size: 8em;
144 | }
145 |
146 | .sub-header__action__icon.fa.fa-gamepad {
147 | -dyn-transform: '"rotate(#{@win-scrollTop}deg) "';
148 | }
149 |
150 | .sub-header__action__text {
151 | font-size: 2.5em;
152 | }
153 |
154 | .sub-header__action__desc {
155 | // text-align: left;
156 | }
157 |
158 |
159 | .sub-header__action__text {
160 | }
161 |
162 |
163 | .sub-header__action__desc pre {
164 | text-align : left;
165 | white-space : pre-wrap;
166 | word-wrap : break-word;
167 | -dyn-padding : '@selectFrom(["0" , "2em" , "2em"])';
168 | -dyn-margin-left : '@selectFrom(["0%" , "0%" , "1%"])';
169 | -dyn-margin-right : '@selectFrom(["0%" , "0%" , "1%"])';
170 | }
171 |
172 |
173 | .sub-header__action__desc code {
174 | // .border-radius(5px,5px,5px,5px);
175 | font-family : Inconsolata;
176 |
177 | }
178 |
179 | // Subheader
180 | // ______ __ _
181 | // / ____/___ ____ / /_____ _(_)___ ___ _____
182 | // / / / __ \/ __ \/ __/ __ `/ / __ \/ _ \/ ___/
183 | // / /___/ /_/ / / / / /_/ /_/ / / / / / __/ /
184 | // \____/\____/_/ /_/\__/\__,_/_/_/ /_/\___/_/
185 | //
186 |
187 | .sub-header__container h1 {
188 | color: #d35400;
189 | }
190 |
191 |
192 | .sub-header__container {
193 | padding-top : 8em;
194 | display : block;
195 | color : black;
196 | }
197 |
198 | hr.sub-header__container__separator {
199 | width: 40%;
200 | }
201 |
202 | @fly-in-from-right: '"translate( #{ (1-@shouldBeVisible()) * 600.0}px, 0px )"';
203 |
204 | .sub-header__container__short_desc {
205 |
206 | padding : 5%;
207 | line-height : 1.5em;
208 | font-size : 1.2em;
209 | margin-left : auto;
210 | margin-right : auto;
211 |
212 | -dyn-width : '@selectFrom(["90%" , "80%" , "60%"])';
213 | -dyn-opacity : '@selectFrom(["1" , "1" , @shouldBeVisible()])';
214 |
215 | & p > code
216 | {
217 | background-color : darken(white, 5%);
218 | padding : 3px;
219 | .border-radius(6px,6px,6px,6px);
220 | }
221 |
222 | & pre {
223 | text-align : left;
224 | white-space : pre-wrap;
225 | word-wrap : break-word;
226 | background-color: red;
227 | }
228 |
229 | & > table {
230 | box-size : border-box;
231 | width : 100%;
232 | background-color : darken(white, 5%);
233 | & th {
234 | min-width : 15%;
235 | text-align : left;
236 | }
237 | .border-radius(6px,6px,6px,6px);
238 | }
239 |
240 |
241 | }
242 |
243 | // __
244 | // / /_____ _____
245 | // / __/ __ \/ ___/
246 | // / /_/ /_/ / /__
247 | // \__/\____/\___/
248 | //
249 |
250 | @lightgray: #ecf0f1;
251 | @darkgray: #34495e;
252 |
253 | .toc {
254 | position : fixed;
255 | -dyn-opacity : '@shouldAppear({when : @win-scrollTop, isHigherThan : @win-height/4}) - 0.3';
256 | -dyn-display : '@selectFrom(["none" , "none" , "block"])';
257 | left : 0px;
258 | z-index : +1;
259 | padding-top : 1em;
260 | padding-bottom : 1em;
261 | background-color : @lightgray;
262 | color : @darkgray;
263 | }
264 |
265 | .toc__section {
266 | box-sizing : border-box;
267 | display : block;
268 | font-size : 1em;
269 | padding : 1em 2em 1em 2em;
270 |
271 |
272 | &.highlight {
273 | color : @lightgray;
274 | background-color : @darkgray;
275 | transition : 200ms;
276 | }
277 |
278 | }
279 |
280 | .toc__section--what_is_it {
281 | -dyn-set-state-highlight: '@isVerticallyVisible("#what-is-it.sub-header__container__short_desc")';
282 | }
283 |
284 | .toc__section--features {
285 | -dyn-set-state-highlight: '@isVerticallyVisible("#features.sub-header__container__short_desc")';
286 | }
287 |
288 | .toc__section--responsiveness {
289 | -dyn-set-state-highlight: '@isVerticallyVisible("#responsiveness.sub-header__container__short_desc")';
290 | }
291 |
292 | .toc__section--dynamic-styles {
293 | -dyn-set-state-highlight: '@isVerticallyVisible("#dynamic-styles.sub-header__container__short_desc")';
294 | }
295 |
296 | .toc__section--api {
297 | -dyn-set-state-highlight: '@isVerticallyVisible("#api.sub-header__container__short_desc")';
298 | }
299 |
300 | // _
301 | // ____ _____ (_)
302 | // / __ `/ __ \/ /
303 | // / /_/ / /_/ / /
304 | // \__,_/ .___/_/
305 | // /_/
306 |
307 | .api__hr {
308 | // display: block;
309 | margin-top: 1em;
310 | margin-bottom: 1em;
311 | margin-left: auto;
312 | margin-right: auto;
313 | padding-top: 10em;
314 | height: 0;
315 | width: 20%;
316 | max-height: 0;
317 | font-size: 1px;
318 | line-height: 0;
319 | // clear: both;
320 | border: none;
321 | border-top: 1px solid #aaaaaa;
322 | border-bottom: 1px solid #ffffff;
323 | }
324 |
325 | .api__element {
326 | margin-top: 4em;
327 | }
328 |
329 | .api__element__name {
330 | display: inline;
331 | font-size: 1.2em;
332 | padding: .5em;
333 | box-sizing: border-box;
334 | border: solid 1px black;
335 | .border-radius(5px,5px,5px,5px);
336 | }
337 |
338 | .api__element__use {
339 | display: block;
340 | margin-top: 2em;
341 | font-family: Inconsolata;
342 | }
343 |
344 |
345 | .api_font() {
346 | font-family: Lato, Helvetica;
347 | font-weight: 300;
348 | font-size: .9em;
349 |
350 | }
351 |
352 | .api__small_title() {
353 | display: block;
354 | padding-top: 1em;
355 | .smallcaps(black, 300);
356 | }
357 |
358 | .api__element__use:before {
359 | .api_font();
360 | .api__small_title();
361 | content: 'invocation:';
362 | }
363 |
364 | .api__element__command_desc:before {
365 | .api_font();
366 | .api__small_title();
367 | content: 'description:';
368 | }
369 |
370 | .api__element__returns {
371 | &:before {
372 | .api_font();
373 | .api__small_title();
374 | content: 'returns:';
375 | }
376 | }
377 |
378 |
379 | .api__element__returns__element {
380 | margin-top: .5em;
381 | width: 100%;
382 | background-color: darken(white,5%);
383 | }
384 |
385 | .api__element__returns__element__value {
386 | width: 20%;
387 | display: inline-block;
388 | }
389 |
390 | .api__element__returns__element__when {
391 | width: 60%;
392 | display: inline-block;
393 | }
394 |
395 | .api__element__returns__element__when:before {
396 | content: 'when';
397 | padding-right: 1em;
398 | .api_font();
399 | }
400 |
401 | .api__element_example {
402 | &:before {
403 | .api_font();
404 | .api__small_title();
405 | content: 'example:';
406 | }
407 | }
408 |
409 | .api__element_variations {
410 | &:before {
411 | .api_font();
412 | .api__small_title();
413 | content: 'variations:';
414 | }
415 | }
416 |
417 | // ____ __
418 | // / __/___ ____ / /____ _____
419 | // / /_/ __ \/ __ \/ __/ _ \/ ___/
420 | // / __/ /_/ / /_/ / /_/ __/ /
421 | // /_/ \____/\____/\__/\___/_/
422 | //
423 |
424 | .sub-header__footer {
425 | margin-top : 5em;
426 | background-color : @darkgray;
427 | }
428 |
429 |
430 | .sub-header__footer__container {
431 | transition: margin 0.3s ease-out;
432 | -dyn-width : '@selectFrom(["90%" , "80%" , "60%"])';
433 | -dyn-margin-left : '@selectFrom(["0" , "10%" , "20%"])';
434 | -dyn-margin-right : '@selectFrom(["0" , "10%" , "20%"])';
435 | display: inline-block;
436 | }
437 |
438 | .aligned-blocks() {
439 | display: block;
440 | float: left;
441 | -dyn-width : '@selectFrom(["100%", "100%", "33%"])';
442 | -dyn-margin-left : '@selectFrom(["10px" , "0px" , "0px"])';
443 | -dyn-margin-right : '@selectFrom(["10px" , "0px" , "0px"])';
444 | -dyn-margin-top : '@selectFrom(["1em" , "1em" , "1em"])';
445 |
446 | }
447 |
448 | .footer__common-properties() {
449 | -dyn-padding-top : '@selectFrom(["1em" , "1em" , "4em"])';
450 | -dyn-padding-bottom : '@selectFrom(["1em" , "1em" , "4em"])';
451 | }
452 |
453 | a:visited, a:link {
454 | color: white;
455 | }
456 |
457 | .sub-header__footer__madeby {
458 |
459 | .aligned-blocks();
460 | .footer__common-properties();
461 | -dyn-text-align : '@selectFrom(["center" , "center" , "right"])';
462 | &:before {
463 | .smallcaps(white, 300);
464 | content: 'made by';
465 | margin-right: 1%;
466 | display: block;
467 | }
468 |
469 | }
470 |
471 | .sub-header__footer__license {
472 | .aligned-blocks();
473 | .footer__common-properties();
474 | text-align: center;
475 | &:before {
476 | .smallcaps(white, 300);
477 | content: 'license';
478 | margin-right: 1%;
479 | display: block;
480 | }
481 | }
482 |
483 | .sub-header__footer__share {
484 | .aligned-blocks();
485 | .footer__common-properties();
486 | -dyn-text-align : '@selectFrom(["center" , "center" , "left"])';
487 | }
488 |
489 |
490 | .sub-header__footer__madeby__address {
491 | font-size: .7em;
492 | }
493 |
494 | .sub-header__footer__madeby__title {
495 | .smallcaps(white, 300);
496 | }
497 |
498 | .sub-header__footer__share__reddit {
499 | padding: 1em;
500 | display: inline;
501 | }
502 |
503 | .sub-header__footer__share__twitter {
504 | padding: 1em;
505 | display: inline;
506 | }
507 |
508 | // __ __
509 | // / /_ ____ ____/ /_ __
510 | // / __ \/ __ \/ __ / / / /
511 | // / /_/ / /_/ / /_/ / /_/ /
512 | // /_.___/\____/\__,_/\__, /
513 | // /____/
514 |
515 | body {
516 | background : url(../img/silhouette_dune_desktop.jpg) no-repeat center center;
517 | background-size : cover;
518 | margin : 0px;
519 | -dyn-width : '@win-width';
520 | -dyn-height : '@win-height';
521 | }
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dyn-css",
3 | "version": "0.8.1",
4 | "homepage": "https://github.com/vzaccaria/DynCSS",
5 | "authors": [
6 | "Vittorio Zaccaria "
7 | ],
8 | "description": "Dynamic rules for css",
9 | "main": "lib/dyncss.js",
10 | "keywords": [
11 | "dynamic",
12 | "css",
13 | "rules"
14 | ],
15 | "license": "MIT",
16 | "private": false,
17 | "ignore": [
18 | "**/.*",
19 | "assets",
20 | "bower.json",
21 | "bower_components",
22 | "config.ls",
23 | "dist",
24 | "gulpfile.ls",
25 | "node_modules",
26 | "package.json",
27 | "vendor"
28 | ],
29 | "dependencies": {
30 | "jquery": "~2.1.0",
31 | "q": "~2.0.0"
32 | }
33 | }
--------------------------------------------------------------------------------
/complete-deploy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | set -e
3 |
4 |
5 | function build_package {
6 | phase "Building the library"
7 | cult build-clean
8 | cult default
9 | rm -rf lib
10 | mkdir -p lib
11 |
12 | phase "Copying the library"
13 | run 'cp dist/js/client.js lib/dyncss.js'
14 |
15 | phase "Testing the library"
16 | run "cd assets/js && make"
17 | }
18 |
19 | function add_package_to_repo {
20 | run "cd $dstdir"
21 | phase "Adding the library to the repo"
22 | run "git add lib/dyncss.js"
23 | }
24 |
25 | usage="
26 | Usage: complete-deploy
27 |
28 | description
29 |
30 | -i --increment
31 | Specify the level of the current version number to increment.
32 | Valid levels are 'major', 'minor', 'patch', and 'prerelease'.
33 | 'patch' is assumed if this option is omitted.
34 |
35 | -d --dry-run
36 | Print the commands without evaluating them.
37 | "
38 |
39 | # Absolute path:
40 | #
41 | # Usage: abs=`get_abs_path ./deploy/static`
42 | # echo $abs
43 | #
44 | function get_abs_path {
45 | dir=$(cd `dirname $1` >/dev/null; pwd )
46 | echo $dir
47 | }
48 | #
49 |
50 | # Get basename:
51 | function get_base_name {
52 | n=$1
53 | n=$(basename "$n")
54 | echo "${n%.*}"
55 | }
56 |
57 |
58 | #if [ $? -eq 0 ]
59 | #then
60 | # echo "it worked"
61 | #else
62 | # echo "it failed"
63 | #fi
64 |
65 | # Source directory
66 | #
67 | srcdir=`dirname $0`
68 | srcdir=`cd $srcdir; pwd`
69 |
70 | #
71 | # Temp directory:
72 | #
73 | # dstdir=`mktemp -d -t bashtmp`
74 | #
75 | # or current:
76 | #
77 | dstdir=`pwd`
78 |
79 | function directory_does_exist {
80 | if [ ! -d "$1" ]; then
81 | echo 'true'
82 | else
83 | echo 'false'
84 | fi
85 | }
86 |
87 | bold=$(tput bold)
88 | reset=$(tput sgr0)
89 | function print_important_message {
90 | printf "${bold}$1${reset}\n"
91 | }
92 |
93 | function ask_for_key {
94 | printf "Press [enter] to continue"
95 | read -s # suppress user input
96 | echo
97 | }
98 |
99 |
100 | # dryrun
101 | dry_run=false
102 | run() {
103 | echo "$1"
104 | if [[ $dry_run == false ]] ; then
105 | eval "$1"
106 | fi
107 | }
108 |
109 | increment=patch
110 | branch=master
111 |
112 |
113 | while (($# > 0)) ; do
114 | option="$1"
115 | shift
116 |
117 | case "$option" in
118 | -h|--help)
119 | echo "$usage"
120 | exit
121 | ;;
122 | -i|--increment) increment="$1" ; shift ;;
123 | -d|--dry-run) dry_run=true ;;
124 | *)
125 | echo "Unrecognized option $option" >&2
126 | exit 1
127 | esac
128 | done
129 |
130 | function phase {
131 | printf "\n"
132 | printf "\n"
133 | printf "# \n"
134 | printf "# $1 \n"
135 | }
136 |
137 | print_important_message "This will commit both the site and a new version of the package"
138 | print_important_message "Make sure you've committed all changes to master"
139 | ask_for_key
140 |
141 | build_package
142 |
143 | add_package_to_repo
144 |
145 | phase "Updating bower package"
146 | name=$(node -p "require('$dstdir/bower.json').name" 2>/dev/null) ||
147 | (echo "Cannot read package name" >&2 ; exit 1)
148 |
149 | print_important_message "Current package is: $name"
150 | version=$(node -p "require('$dstdir/bower.json').version" 2>/dev/null) ||
151 | (echo "Cannot read package version " >&2 ; exit 1)
152 |
153 | print_important_message "Current package version is: $version"
154 | next_version=$("semver" -i "$increment" "$version")
155 |
156 |
157 | message_template='Version X.Y.Z'
158 | tag_template=vX.Y.Z
159 | message="${message_template//X.Y.Z/$next_version}"
160 | tag="${tag_template//X.Y.Z/$next_version}"
161 |
162 |
163 | run "node -e '$(echo "
164 | var o = require('$dstdir/bower.json');
165 | o.version = '$next_version';
166 | var s = JSON.stringify(o, null, 2) + '\n';
167 | require('fs').writeFileSync('$dstdir/bower.json', s);
168 | " | tr "'" '"' | tr -d "\n" | sed "s/^[ ]*//" | tr -s " ")'"
169 |
170 | phase "Committing bower package"
171 | run "git add bower.json"
172 | run "git commit --message '$message'"
173 | run "git tag --annotate '$tag' --message '$message'"
174 | run "git push origin 'refs/heads/$branch' 'refs/tags/$tag'"
175 |
176 | phase "Updating the website"
177 | run 'cult ftp'
--------------------------------------------------------------------------------
/config.ls:
--------------------------------------------------------------------------------
1 | _module = ->
2 |
3 |
4 | iface = {
5 |
6 | # main properties
7 | destination:'dist'
8 | remote:'dyn-css'
9 |
10 | vendor-js:
11 | "./bower_components/jquery/dist/jquery.min.js"
12 | "./dist/js/build/site.js"
13 | ...
14 |
15 | # client files
16 | client-ls:
17 | "./assets/js/*.ls"
18 | ...
19 |
20 | client-brfy-roots: [ 'entry.js' ]
21 |
22 | client-html:
23 | "./assets/*.jade"
24 | "./assets/views/*.jade"
25 | ...
26 |
27 | client-less:
28 | './assets/less/*.less'
29 | ...
30 |
31 | directives:[
32 | './assets/directives/*.sjs'
33 | ]
34 |
35 | # vendor files
36 | vendor-css:
37 | './assets/css/*.css'
38 | ...
39 |
40 | # other assets
41 | font-dir:'./assets/fonts'
42 |
43 | img-dir:'./assets/img'
44 |
45 | data-to-be-copied:[
46 | "./data/*.json"
47 | "./assets/less/*.dss"
48 | ]
49 |
50 |
51 | other-deps: []
52 |
53 | }
54 |
55 | return iface
56 |
57 | module.exports = _module()
--------------------------------------------------------------------------------
/dist/css/vendor.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Obsidian style
3 | * ported by Alexander Marenin (http://github.com/ioncreature)
4 | */
5 |
6 | .hljs {
7 | display: block; padding: 0.5em;
8 | background: #282B2E;
9 | }
10 |
11 | .hljs-keyword,
12 | .hljs-literal,
13 | .hljs-change,
14 | .hljs-winutils,
15 | .hljs-flow,
16 | .lisp .hljs-title,
17 | .clojure .hljs-built_in,
18 | .nginx .hljs-title,
19 | .css .hljs-id,
20 | .tex .hljs-special {
21 | color: #93C763;
22 | }
23 |
24 | .hljs-number {
25 | color: #FFCD22;
26 | }
27 |
28 | .hljs {
29 | color: #E0E2E4;
30 | }
31 |
32 | .css .hljs-tag,
33 | .css .hljs-pseudo {
34 | color: #D0D2B5;
35 | }
36 |
37 | .hljs-attribute,
38 | .hljs .hljs-constant {
39 | color: #668BB0;
40 | }
41 |
42 | .xml .hljs-attribute {
43 | color: #B3B689;
44 | }
45 |
46 | .xml .hljs-tag .hljs-value {
47 | color: #E8E2B7;
48 | }
49 |
50 | .hljs-code,
51 | .hljs-class .hljs-title,
52 | .hljs-header {
53 | color: white;
54 | }
55 |
56 | .hljs-class,
57 | .hljs-hexcolor {
58 | color: #93C763;
59 | }
60 |
61 | .hljs-regexp {
62 | color: #D39745;
63 | }
64 |
65 | .hljs-at_rule,
66 | .hljs-at_rule .hljs-keyword {
67 | color: #A082BD;
68 | }
69 |
70 | .hljs-doctype {
71 | color: #557182;
72 | }
73 |
74 | .hljs-link_url,
75 | .hljs-tag,
76 | .hljs-tag .hljs-title,
77 | .hljs-bullet,
78 | .hljs-subst,
79 | .hljs-emphasis,
80 | .haskell .hljs-type,
81 | .hljs-preprocessor,
82 | .hljs-pragma,
83 | .ruby .hljs-class .hljs-parent,
84 | .hljs-built_in,
85 | .sql .hljs-aggregate,
86 | .django .hljs-template_tag,
87 | .django .hljs-variable,
88 | .smalltalk .hljs-class,
89 | .hljs-javadoc,
90 | .django .hljs-filter .hljs-argument,
91 | .smalltalk .hljs-localvars,
92 | .smalltalk .hljs-array,
93 | .hljs-attr_selector,
94 | .hljs-pseudo,
95 | .hljs-addition,
96 | .hljs-stream,
97 | .hljs-envvar,
98 | .apache .hljs-tag,
99 | .apache .hljs-cbracket,
100 | .tex .hljs-command,
101 | .hljs-prompt {
102 | color: #8CBBAD;
103 | }
104 |
105 | .hljs-string {
106 | color: #EC7600;
107 | }
108 |
109 | .hljs-comment,
110 | .java .hljs-annotation,
111 | .hljs-blockquote,
112 | .hljs-horizontal_rule,
113 | .python .hljs-decorator,
114 | .hljs-template_comment,
115 | .hljs-pi,
116 | .hljs-deletion,
117 | .hljs-shebang,
118 | .apache .hljs-sqbracket,
119 | .tex .hljs-formula {
120 | color: #818E96;
121 | }
122 |
123 | .hljs-keyword,
124 | .hljs-literal,
125 | .css .hljs-id,
126 | .hljs-phpdoc,
127 | .hljs-title,
128 | .hljs-header,
129 | .haskell .hljs-type,
130 | .vbscript .hljs-built_in,
131 | .sql .hljs-aggregate,
132 | .rsl .hljs-built_in,
133 | .smalltalk .hljs-class,
134 | .diff .hljs-header,
135 | .hljs-chunk,
136 | .hljs-winutils,
137 | .bash .hljs-variable,
138 | .apache .hljs-tag,
139 | .tex .hljs-special,
140 | .hljs-request,
141 | .hljs-at_rule .hljs-keyword,
142 | .hljs-status {
143 | font-weight: bold;
144 | }
145 |
146 | .coffeescript .javascript,
147 | .javascript .xml,
148 | .tex .hljs-formula,
149 | .xml .javascript,
150 | .xml .vbscript,
151 | .xml .css,
152 | .xml .hljs-cdata {
153 | opacity: 0.5;
154 | }
155 |
--------------------------------------------------------------------------------
/dist/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vzaccaria/DynCSS/28411828f1235ed10235e4c62bb4bce7a71a0ec2/dist/img/background.jpg
--------------------------------------------------------------------------------
/dist/img/silhouette_dune_desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vzaccaria/DynCSS/28411828f1235ed10235e4c62bb4bce7a71a0ec2/dist/img/silhouette_dune_desktop.jpg
--------------------------------------------------------------------------------
/gulpfile.ls:
--------------------------------------------------------------------------------
1 |
2 | { client-html, client-less, client-ls, client-brfy-roots, directives, other-deps } = require('./config')
3 | { vendor-js, vendor-css, , data-to-be-copied } = require('./config')
4 | { remote, destination, font-dir, img-dir } = require('./config')
5 |
6 | client-js = [ "#destination/js/build/#s" for s in client-brfy-roots ]
7 |
8 | files-to-watch = client-ls ++ client-less ++ client-html ++ directives ++ other-deps
9 |
10 | force-file-reload = [
11 | "#destination/**/*.html"
12 | "#destination/**/*.css"
13 | "#destination/**/*.js"
14 | "#destination/**/*.png"
15 | "#destination/**/*.jpg"
16 | ]
17 |
18 | require! 'gulp'
19 | jade = require 'gulp-jade'
20 | stylus = require 'gulp-stylus'
21 | ftp = require 'gulp-ftp'
22 | less = require 'gulp-less'
23 | browserify = require 'gulp-browserify'
24 | live = require 'gulp-livescript'
25 | uglify = require 'gulp-uglify'
26 | concat = require 'gulp-concat'
27 | rename = require 'gulp-rename'
28 | exec = require 'gulp-exec'
29 | clean = require 'gulp-clean'
30 | filesize = require('gulp-filesize');
31 | spawn = require 'gulp-spawn'
32 | changed = require 'gulp-changed'
33 | plumber = require('gulp-plumber');
34 | cr = require '/Users/zaccaria/.ssh/sftp_credentials'
35 |
36 |
37 |
38 | EXPRESS_PORT = 4000;
39 | EXPRESS_ROOT = destination;
40 | LIVERELOAD_PORT = 35729;
41 |
42 | start-express = ->
43 | express = require('express');
44 | app = express();
45 | app.use(require('connect-livereload')());
46 | app.use(express.static(EXPRESS_ROOT, {maxAge: 0}));
47 | app.listen(EXPRESS_PORT);
48 |
49 | var lr
50 |
51 | start-livereload = ->
52 | lr := require('tiny-lr')()
53 | lr.listen(LIVERELOAD_PORT)
54 |
55 |
56 | notifyLivereload = (event) ->
57 | fileName = require('path').relative(EXPRESS_ROOT, event.path);
58 | lr.changed body: { files: [fileName] }
59 |
60 |
61 | gulp.task 'build-html', ->
62 | gulp.src client-html
63 | .pipe plumber()
64 | .pipe jade()
65 | .pipe gulp.dest "#destination/html"
66 |
67 | gulp.task 'build-index', ['build-html'] ->
68 | gulp.src "#destination/html/index.html"
69 | .pipe gulp.dest "#destination"
70 |
71 | gulp.task 'build-client-js', ['build-client-ls'], ->
72 | gulp.src client-js, { read: false }
73 | .pipe plumber()
74 | .pipe browserify {
75 | insertGlobals : false
76 | }
77 | .pipe concat('client.js')
78 | .pipe gulp.dest "#destination/js"
79 |
80 | gulp.task 'build-client-ls', ->
81 | gulp.src client-ls
82 | .pipe plumber()
83 | .pipe changed "#destination/js/build"
84 | .pipe live()
85 | .pipe gulp.dest "#destination/js/build"
86 |
87 | gulp.task 'build-vendor-js-prod', ['build-client-js'],->
88 | gulp.src vendor-js
89 | .pipe(concat('vendor.js'))
90 | .pipe filesize()
91 | .pipe gulp.dest "#destination/js"
92 | .pipe uglify()
93 | .pipe rename('vendor.min.js')
94 | .pipe filesize()
95 | .pipe gulp.dest "#destination/js"
96 |
97 | gulp.task 'build-vendor-js', ['build-client-js'], ->
98 | gulp.src vendor-js
99 | .pipe(concat('vendor.js'))
100 | .pipe gulp.dest "#destination/js"
101 |
102 | gulp.task 'build-less', ->
103 | gulp.src client-less
104 | .pipe plumber()
105 | .pipe changed "#destination/css/build"
106 | .pipe less()
107 | .pipe gulp.dest "#destination/css/build"
108 |
109 | gulp.task 'build-css', ['build-less'], ->
110 | gulp.src "#destination/css/build/*.css"
111 | .pipe plumber()
112 | .pipe concat('client.css')
113 | .pipe gulp.dest "#destination/css"
114 |
115 | gulp.task 'build-vendor-css', ->
116 | gulp.src vendor-css
117 | .pipe concat('vendor.css')
118 | .pipe gulp.dest "#destination/css"
119 |
120 | gulp.task 'build-img', ->
121 | gulp.src ["#img-dir/*.png", "#img-dir/*.jpg"]
122 | .pipe changed "#destination/img"
123 | .pipe gulp.dest "#destination/img"
124 |
125 | gulp.task 'build-fonts', ->
126 | gulp.src [ "#font-dir/*.woff"
127 | "#font-dir/*.otf"
128 | "#font-dir/*.eot"
129 | "#font-dir/*.svg"
130 | "#font-dir/*.ttf"
131 | ]
132 | .pipe changed "#destination/fonts"
133 | .pipe gulp.dest "#destination/fonts"
134 |
135 | gulp.task 'ftp', ->
136 | gulp.src ["#destination/**"]
137 | .pipe ftp {
138 | host: '217.64.195.216'
139 | user: 'vittoriozaccaria.net'
140 | pass: cr['217.64.195.216']['vittoriozaccaria.net']
141 | remote-path: "htdocs/#remote"
142 | }
143 |
144 |
145 | gulp.task 'sjs', ->
146 | gulp.src directives
147 | .pipe changed "#destination/js"
148 | .pipe((spawn { cmd: 'sweet-angle', args: [ '-a', 'application', '/dev/stdin'] }).on 'error', console.log)
149 | .pipe gulp.dest "#destination/js"
150 |
151 |
152 | gulp.task 'build-clean', ->
153 | gulp.src destination, {read: false}
154 | .pipe clean()
155 |
156 | gulp.task 'js-build-clean', ->
157 | gulp.src "#destination/js/build", {read: false}
158 | .pipe clean()
159 |
160 | gulp.task 'watch-build', ->
161 | startExpress();
162 | startLivereload();
163 | gulp.watch(force-file-reload, notifyLivereload);
164 | files-to-watch = client-ls ++ client-less ++ client-html ++ directives ++ other-deps
165 | gulp.watch(files-to-watch, ["default"])
166 |
167 |
168 | fs = require('fs')
169 |
170 | gulp.task 'build-package-json', ->
171 | fs.readdir "./node_modules", (err, dirs) ->
172 | for dir in dirs
173 | if dir.index-of(".") != 0
174 | packageJsonFile = "./node_modules/#dir/package.json"
175 | if fs.existsSync packageJsonFile
176 | fs.readFile packageJsonFile, (err, data) ->
177 | json = JSON.parse(data)
178 | console.log "\"#{json.name}\": \"#{json.version}\", "
179 |
180 | gulp.task 'copy-data', ->
181 | gulp.src data-to-be-copied
182 | .pipe changed("#destination/data")
183 | .pipe gulp.dest "#destination/data"
184 |
185 | gulp.task 'default', [
186 | \build-index
187 | \build-client-js
188 | \build-vendor-js
189 | \build-vendor-css
190 | \build-css
191 | \build-fonts
192 | \build-img
193 | \copy-data
194 | \sjs
195 | ...
196 | ]
197 |
198 | gulp.task 'production', [
199 | \build-index
200 | \build-client-js
201 | \build-vendor-js-prod
202 | \build-vendor-css
203 | \build-css
204 | \build-fonts
205 | \build-img
206 | \copy-data
207 | \sjs
208 | ...
209 | ]
210 |
211 | runSequence = require('run-sequence');
212 |
213 | gulp.task 'dev', (done) ->
214 | runSequence 'build-clean', 'default', 'watch-build', done
215 |
216 | gulp.task 'deploy', (done) ->
217 | runSequence 'build-clean', 'default', 'ftp'
218 |
--------------------------------------------------------------------------------
/lib/dyncss.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o " + css[k] + ")");
208 | }
209 | windowDi.dynCss.el.css((ref$ = {}, ref$[k + ""] = v, ref$));
210 | this.oldValue == null && (this.oldValue = {});
211 | this.oldValue[k] = v;
212 | changed = true;
213 | }
214 | }
215 | return newValue = JSON.stringify(css);
216 | function fn$(){
217 | switch (false) {
218 | case !!windowDi.dynCss.config.dontComputeInvisible:
219 | return true;
220 | case windowDi.dynCss.el.css('display') === 'none':
221 | return true;
222 | default:
223 | return false;
224 | }
225 | }
226 | }
227 | };
228 | }.call(this, actions, sel));
229 | }
230 | };
231 | return {
232 | innerModule: innerModule,
233 | buildHandlers: buildHandlers
234 | };
235 | };
236 | module.exports = dynCss;
237 | }).call(this);
238 |
239 | },{"./lib":3}],2:[function(require,module,exports){
240 | (function(){
241 | var cssParse, builtIn, dynCss, _q, buildHandlers, blue, red, normal, entryDebugMessage, scrollHandler, refreshHandler, decimate, iOS, counter, lt, fixedTtc, installCustomRaf, installScrollHandler, parseCss, _loaded_d, _loaded_p, results, pArray, r;
242 | cssParse = require('css-parse');
243 | builtIn = require('./lib');
244 | dynCss = require('./core');
245 | _q = require('q');
246 | buildHandlers = dynCss(window, document, jQuery).buildHandlers;
247 | blue = '#3498db';
248 | red = '#c0392b';
249 | normal = 'black';
250 | entryDebugMessage = function(m){
251 | if (window.dynCss.config.debug) {
252 | return console.log("%cdyncss-entry: %c" + m, "color: " + blue, "color: " + normal);
253 | }
254 | };
255 | refreshHandler = function(changed){
256 | if (changed) {
257 | return window.dynCss.api.forceRedraw();
258 | }
259 | };
260 | decimate = 1;
261 | iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
262 | counter = 0;
263 | lt = 0;
264 | fixedTtc = 1000 / 1;
265 | installCustomRaf = function(){
266 | return window.customRequestAnimationFrame = function(cb){
267 | var ct, ttc;
268 | ct = new Date().getTime();
269 | ttc = Math.max(0, 16 - (ct - lt));
270 | if (fixedTtc != null) {
271 | setTimeout(cb, fixedTtc, true);
272 | } else {
273 | setTimeout(cb, ttc, true);
274 | }
275 | return lt = ct + ttc;
276 | };
277 | };
278 | installScrollHandler = function(options){
279 | scrollHandler = function(){
280 | if (window.dynCss.config.useRAF) {
281 | return window.requestAnimationFrame(function(){
282 | if (counter % decimate === 0) {
283 | refreshHandler(false);
284 | }
285 | return counter = counter + 1;
286 | });
287 | } else {
288 | if (counter % decimate === 0) {
289 | refreshHandler(false);
290 | }
291 | return counter = counter + 1;
292 | }
293 | };
294 | if ((options != null ? options.onlyOnResize : void 8) != null) {
295 | return window.onresize = scrollHandler;
296 | } else {
297 | if ((options != null ? options.onlyOnStart : void 8) == null) {
298 | window.onscroll = scrollHandler;
299 | window.ontouchmove = scrollHandler;
300 | return window.onresize = scrollHandler;
301 | }
302 | }
303 | };
304 | entryDebugMessage("Scanning for css");
305 | parseCss = function(n){
306 | var _d;
307 | entryDebugMessage("Loading " + n.href);
308 | _d = _q.defer();
309 | if (n.href != null) {
310 | $.get(n.href, function(it){
311 | var rules;
312 | entryDebugMessage("Loaded " + n.href);
313 | rules = cssParse(it).stylesheet.rules;
314 | refreshHandler = buildHandlers(rules, refreshHandler);
315 | if (refreshHandler != null) {
316 | if (iOS) {
317 | installScrollHandler({
318 | onlyOnStart: true
319 | });
320 | } else {
321 | installScrollHandler();
322 | }
323 | }
324 | return _d.resolve();
325 | });
326 | }
327 | return _d.promise;
328 | };
329 | _loaded_d = _q.defer();
330 | _loaded_p = _loaded_d.promise;
331 | window.onload = function(){
332 | entryDebugMessage("Content loaded");
333 | return _loaded_d.resolve();
334 | };
335 | $(document).ready = function(){
336 | return entryDebugMessage("Document parsed.");
337 | };
338 | results = $('link[type="text/css"]');
339 | pArray = (function(){
340 | var i$, ref$, len$, results$ = [];
341 | for (i$ = 0, len$ = (ref$ = results).length; i$ < len$; ++i$) {
342 | r = ref$[i$];
343 | results$.push(parseCss(r));
344 | }
345 | return results$;
346 | }()).concat([_loaded_p]);
347 | _q.all(pArray).then(function(){
348 | entryDebugMessage("Initializing handler");
349 | return scrollHandler();
350 | });
351 | window.dynCss.api.initVariable = function(vr, value){
352 | return window.dynCss.lib[vr] = value;
353 | };
354 | window.dynCss.api.setVariable = function(vr, value){
355 | window.dynCss.api.initVariable(vr, value);
356 | return scrollHandler();
357 | };
358 | window.dynCss.api.initToggle = function(vr, value1, value2){
359 | window.dynCss.api.initVariable(vr, value1);
360 | window.dynCss.api.initVariable(vr + "Value0", value1);
361 | window.dynCss.api.initVariable(vr + "Value1", value2);
362 | return entryDebugMessage("Initialising variable " + vr + " to " + value1);
363 | };
364 | window.dynCss.api.toggle = function(vr){
365 | var vv, v1, v2;
366 | vv = window.dynCss.lib[vr];
367 | v1 = window.dynCss.lib[vr + "Value0"];
368 | v2 = window.dynCss.lib[vr + "Value1"];
369 | if (vv === v1) {
370 | window.dynCss.api.setVariable(vr, v2);
371 | return entryDebugMessage("Setting " + vr + " to " + v2);
372 | } else {
373 | window.dynCss.api.setVariable(vr, v1);
374 | return entryDebugMessage("Setting " + vr + " to " + v1);
375 | }
376 | };
377 | }).call(this);
378 |
379 | },{"./core":1,"./lib":3,"css-parse":4,"q":6}],3:[function(require,module,exports){
380 | (function(){
381 | var debug, perspective, sat, asPercentageOf, asRemainingPercentageOf, shouldDisappear, transitionToOne, shouldAppear, selectFrom, ifThenElse, isVerticallyVisible, topOf, bottomOf, leftOf, rightOf, _module;
382 | debug = false;
383 | perspective = function(px){
384 | return "perspective(" + px + "px) ";
385 | };
386 | sat = function(x){
387 | switch (false) {
388 | case !(x > 1):
389 | return 1;
390 | case !(x < 0):
391 | return 0;
392 | default:
393 | return x;
394 | }
395 | };
396 | asPercentageOf = curry$(function(x$, y$){
397 | return x$ / y$;
398 | });
399 | asRemainingPercentageOf = function(x, y){
400 | return 1 - asPercentageOf(x, y);
401 | };
402 | shouldDisappear = function(context){
403 | var isHigherThan, isLowerThan, wn, v;
404 | isHigherThan = context.isHigherThan, isLowerThan = context.isLowerThan, wn = context.when;
405 | if (isHigherThan != null && wn != null) {
406 | return sat(asRemainingPercentageOf(wn, isHigherThan));
407 | }
408 | if (isLowerThan != null && wn != null) {
409 | v = sat(asPercentageOf(wn, isLowerThan));
410 | return v;
411 | }
412 | };
413 | transitionToOne = function(context, power){
414 | var int, vv, direction, start, stop, val, orig, pp;
415 | power == null && (power = 1);
416 | start = context.start, stop = context.stop, val = context.when;
417 | orig = val;
418 | pp = (function(){
419 | switch (false) {
420 | case !(start < stop && val < start):
421 | return 0;
422 | case !(start < stop && val > stop):
423 | return 1;
424 | case !(start < stop):
425 | return (val - start) / (stop - start);
426 | case !(start > stop && val > start):
427 | return 1;
428 | case !(start > stop && val < stop):
429 | return 0;
430 | case !(start > stop):
431 | return 1 - (val - stop) / (start - stop);
432 | }
433 | }());
434 | vv = sat(pp);
435 | return Math.pow(vv, power);
436 | };
437 | shouldAppear = function(context){
438 | var isHigherThan, isLowerThan, wn, vv, int;
439 | isHigherThan = context.isHigherThan, isLowerThan = context.isLowerThan, wn = context.when;
440 | wn = context['when'];
441 | if (isHigherThan != null && wn != null) {
442 | int = asPercentageOf(wn, isHigherThan);
443 | }
444 | if (isLowerThan != null && wn != null) {
445 | int = asRemainingPercentageOf(wn, isLowerThan);
446 | }
447 | vv = sat(int);
448 | if (debug) {
449 | console.log("final: " + vv + ", intermediate: " + int + ", is-higher: " + isHigherThan + ", is-lower: " + isLowerThan);
450 | }
451 | return vv;
452 | };
453 | selectFrom = function(values){
454 | var dt, vv, i$, ref$, len$, i, b, error;
455 | dt = window.dynCss.data['responsive'];
456 | try {
457 | if (dt.compiled != null && values.length > 0) {
458 | vv = dt.compiled();
459 | for (i$ = 0, len$ = (ref$ = dt.breakpoints).length; i$ < len$; ++i$) {
460 | i = i$;
461 | b = ref$[i$];
462 | if (vv < b || i === values.length - 1) {
463 | return values[i];
464 | }
465 | }
466 | return values[values.length - 1];
467 | }
468 | } catch (e$) {
469 | return error = e$;
470 | }
471 | };
472 | ifThenElse = function(cond, v1, v2){
473 | if (cond) {
474 | return v1;
475 | } else {
476 | return v2;
477 | }
478 | };
479 | isVerticallyVisible = function(el, threshold){
480 | var r, w, vp, value;
481 | r = jQuery(el)[0].getBoundingClientRect();
482 | w = jQuery(window);
483 | vp = {
484 | top: w.scrollTop(),
485 | bottom: w.scrollTop() + w.height()
486 | };
487 | threshold == null && (threshold = w.height() / 3);
488 | value = (function(){
489 | switch (false) {
490 | case !(r.top >= 0 && r.top < threshold):
491 | return true;
492 | case !(r.top < 0 && r.bottom > threshold):
493 | return true;
494 | default:
495 | return false;
496 | }
497 | }());
498 | return value;
499 | };
500 | topOf = function(el){
501 | if (el !== window) {
502 | return jQuery(el).offset().top - $(window).scrollTop();
503 | } else {
504 | return 0;
505 | }
506 | };
507 | bottomOf = function(el){
508 | if (el !== window) {
509 | return jQuery(el).offset().top - $(window).scrollTop() + parseInt(jQuery(el).css('margin-bottom')) + jQuery(el).innerHeight();
510 | } else {
511 | return $(window).height();
512 | }
513 | };
514 | leftOf = function(el){
515 | if (el !== window) {
516 | return jQuery(el).offset().left + parseInt(jQuery(el).css('margin-right'));
517 | } else {
518 | return 0;
519 | }
520 | };
521 | rightOf = function(el){
522 | if (el !== window) {
523 | return jQuery(el).offset().left + parseInt(jQuery(el).css('margin-right')) + jQuery(el).innerWidth();
524 | } else {
525 | return $(window).width();
526 | }
527 | };
528 | _module = function(){
529 | var iface;
530 | iface = {
531 | shouldDisappear: shouldDisappear,
532 | convergeToZero: shouldDisappear,
533 | shouldAppear: shouldAppear,
534 | convergeToOne: shouldAppear,
535 | transitionToOne: transitionToOne,
536 | perspective: perspective,
537 | selectFrom: selectFrom,
538 | isVerticallyVisible: isVerticallyVisible,
539 | 'if': ifThenElse,
540 | fixedTopEdge: topOf,
541 | fixedBottomEdge: bottomOf,
542 | fixedRightEdge: rightOf,
543 | fixedLeftEdge: leftOf,
544 | pos: function(el){
545 | return $(el).offset();
546 | },
547 | fixedHorizontalCenter: function(it){
548 | return (rightOf(it) + leftOf(it)) / 2;
549 | },
550 | fixedVerticalCenter: function(it){
551 | return (topOf(it) + bottomOf(it)) / 2;
552 | },
553 | morph: function(c, v1, v2){
554 | var vv;
555 | vv = v1 * (1 - c) + v2 * c;
556 | return vv;
557 | },
558 | shouldBeVisible: function(){
559 | var $wTop, $el, $elTop, $elH, $wHeight, $setOff, v;
560 | $wTop = $(window).scrollTop();
561 | $el = jQuery(window.dynCss.el);
562 | $elTop = $el.offset().top;
563 | $elH = $el.innerHeight();
564 | $wHeight = $(window).height();
565 | $setOff = $elTop;
566 | v = shouldAppear({
567 | when: $(window).scrollTop(),
568 | isHigherThan: $setOff
569 | });
570 | if (debug) {
571 | console.log("top = " + $wTop + ", completed-at = " + $setOff + ", visible = " + v + ", eltop = " + $elTop + ", el-h = " + $elH);
572 | }
573 | return v;
574 | }
575 | };
576 | return iface;
577 | };
578 | module.exports = _module();
579 | function curry$(f, bound){
580 | var context,
581 | _curry = function(args) {
582 | return f.length > 1 ? function(){
583 | var params = args ? args.concat() : [];
584 | context = bound ? context || this : this;
585 | return params.push.apply(params, arguments) <
586 | f.length && arguments.length ?
587 | _curry.call(context, params) : f.apply(context, params);
588 | } : f;
589 | };
590 | return _curry();
591 | }
592 | }).call(this);
593 |
594 | },{}],4:[function(require,module,exports){
595 |
596 | module.exports = function(css, options){
597 | options = options || {};
598 |
599 | /**
600 | * Positional.
601 | */
602 |
603 | var lineno = 1;
604 | var column = 1;
605 |
606 | /**
607 | * Update lineno and column based on `str`.
608 | */
609 |
610 | function updatePosition(str) {
611 | var lines = str.match(/\n/g);
612 | if (lines) lineno += lines.length;
613 | var i = str.lastIndexOf('\n');
614 | column = ~i ? str.length - i : column + str.length;
615 | }
616 |
617 | /**
618 | * Mark position and patch `node.position`.
619 | */
620 |
621 | function position() {
622 | var start = { line: lineno, column: column };
623 | if (!options.position) return positionNoop;
624 |
625 | return function(node){
626 | node.position = {
627 | start: start,
628 | end: { line: lineno, column: column },
629 | source: options.source
630 | };
631 |
632 | whitespace();
633 | return node;
634 | }
635 | }
636 |
637 | /**
638 | * Return `node`.
639 | */
640 |
641 | function positionNoop(node) {
642 | whitespace();
643 | return node;
644 | }
645 |
646 | /**
647 | * Error `msg`.
648 | */
649 |
650 | function error(msg) {
651 | var err = new Error(msg + ' near line ' + lineno + ':' + column);
652 | err.filename = options.source;
653 | err.line = lineno;
654 | err.column = column;
655 | err.source = css;
656 | throw err;
657 | }
658 |
659 | /**
660 | * Parse stylesheet.
661 | */
662 |
663 | function stylesheet() {
664 | return {
665 | type: 'stylesheet',
666 | stylesheet: {
667 | rules: rules()
668 | }
669 | };
670 | }
671 |
672 | /**
673 | * Opening brace.
674 | */
675 |
676 | function open() {
677 | return match(/^{\s*/);
678 | }
679 |
680 | /**
681 | * Closing brace.
682 | */
683 |
684 | function close() {
685 | return match(/^}/);
686 | }
687 |
688 | /**
689 | * Parse ruleset.
690 | */
691 |
692 | function rules() {
693 | var node;
694 | var rules = [];
695 | whitespace();
696 | comments(rules);
697 | while (css.charAt(0) != '}' && (node = atrule() || rule())) {
698 | rules.push(node);
699 | comments(rules);
700 | }
701 | return rules;
702 | }
703 |
704 | /**
705 | * Match `re` and return captures.
706 | */
707 |
708 | function match(re) {
709 | var m = re.exec(css);
710 | if (!m) return;
711 | var str = m[0];
712 | updatePosition(str);
713 | css = css.slice(str.length);
714 | return m;
715 | }
716 |
717 | /**
718 | * Parse whitespace.
719 | */
720 |
721 | function whitespace() {
722 | match(/^\s*/);
723 | }
724 |
725 | /**
726 | * Parse comments;
727 | */
728 |
729 | function comments(rules) {
730 | var c;
731 | rules = rules || [];
732 | while (c = comment()) rules.push(c);
733 | return rules;
734 | }
735 |
736 | /**
737 | * Parse comment.
738 | */
739 |
740 | function comment() {
741 | var pos = position();
742 | if ('/' != css.charAt(0) || '*' != css.charAt(1)) return;
743 |
744 | var i = 2;
745 | while (null != css.charAt(i) && ('*' != css.charAt(i) || '/' != css.charAt(i + 1))) ++i;
746 | i += 2;
747 |
748 | var str = css.slice(2, i - 2);
749 | column += 2;
750 | updatePosition(str);
751 | css = css.slice(i);
752 | column += 2;
753 |
754 | return pos({
755 | type: 'comment',
756 | comment: str
757 | });
758 | }
759 |
760 | /**
761 | * Parse selector.
762 | */
763 |
764 | function selector() {
765 | var m = match(/^([^{]+)/);
766 | if (!m) return;
767 | return trim(m[0]).split(/\s*,\s*/);
768 | }
769 |
770 | /**
771 | * Parse declaration.
772 | */
773 |
774 | function declaration() {
775 | var pos = position();
776 |
777 | // prop
778 | var prop = match(/^(\*?[-#\/\*\w]+(\[[0-9a-z_-]+\])?)\s*/);
779 | if (!prop) return;
780 | prop = trim(prop[0]);
781 |
782 | // :
783 | if (!match(/^:\s*/)) return error("property missing ':'");
784 |
785 | // val
786 | var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);
787 | if (!val) return error('property missing value');
788 |
789 | var ret = pos({
790 | type: 'declaration',
791 | property: prop,
792 | value: trim(val[0])
793 | });
794 |
795 | // ;
796 | match(/^[;\s]*/);
797 |
798 | return ret;
799 | }
800 |
801 | /**
802 | * Parse declarations.
803 | */
804 |
805 | function declarations() {
806 | var decls = [];
807 |
808 | if (!open()) return error("missing '{'");
809 | comments(decls);
810 |
811 | // declarations
812 | var decl;
813 | while (decl = declaration()) {
814 | decls.push(decl);
815 | comments(decls);
816 | }
817 |
818 | if (!close()) return error("missing '}'");
819 | return decls;
820 | }
821 |
822 | /**
823 | * Parse keyframe.
824 | */
825 |
826 | function keyframe() {
827 | var m;
828 | var vals = [];
829 | var pos = position();
830 |
831 | while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
832 | vals.push(m[1]);
833 | match(/^,\s*/);
834 | }
835 |
836 | if (!vals.length) return;
837 |
838 | return pos({
839 | type: 'keyframe',
840 | values: vals,
841 | declarations: declarations()
842 | });
843 | }
844 |
845 | /**
846 | * Parse keyframes.
847 | */
848 |
849 | function atkeyframes() {
850 | var pos = position();
851 | var m = match(/^@([-\w]+)?keyframes */);
852 |
853 | if (!m) return;
854 | var vendor = m[1];
855 |
856 | // identifier
857 | var m = match(/^([-\w]+)\s*/);
858 | if (!m) return error("@keyframes missing name");
859 | var name = m[1];
860 |
861 | if (!open()) return error("@keyframes missing '{'");
862 |
863 | var frame;
864 | var frames = comments();
865 | while (frame = keyframe()) {
866 | frames.push(frame);
867 | frames = frames.concat(comments());
868 | }
869 |
870 | if (!close()) return error("@keyframes missing '}'");
871 |
872 | return pos({
873 | type: 'keyframes',
874 | name: name,
875 | vendor: vendor,
876 | keyframes: frames
877 | });
878 | }
879 |
880 | /**
881 | * Parse supports.
882 | */
883 |
884 | function atsupports() {
885 | var pos = position();
886 | var m = match(/^@supports *([^{]+)/);
887 |
888 | if (!m) return;
889 | var supports = trim(m[1]);
890 |
891 | if (!open()) return error("@supports missing '{'");
892 |
893 | var style = comments().concat(rules());
894 |
895 | if (!close()) return error("@supports missing '}'");
896 |
897 | return pos({
898 | type: 'supports',
899 | supports: supports,
900 | rules: style
901 | });
902 | }
903 |
904 | /**
905 | * Parse host.
906 | */
907 |
908 | function athost() {
909 | var pos = position();
910 | var m = match(/^@host */);
911 |
912 | if (!m) return;
913 |
914 | if (!open()) return error("@host missing '{'");
915 |
916 | var style = comments().concat(rules());
917 |
918 | if (!close()) return error("@host missing '}'");
919 |
920 | return pos({
921 | type: 'host',
922 | rules: style
923 | });
924 | }
925 |
926 | /**
927 | * Parse media.
928 | */
929 |
930 | function atmedia() {
931 | var pos = position();
932 | var m = match(/^@media *([^{]+)/);
933 |
934 | if (!m) return;
935 | var media = trim(m[1]);
936 |
937 | if (!open()) return error("@media missing '{'");
938 |
939 | var style = comments().concat(rules());
940 |
941 | if (!close()) return error("@media missing '}'");
942 |
943 | return pos({
944 | type: 'media',
945 | media: media,
946 | rules: style
947 | });
948 | }
949 |
950 | /**
951 | * Parse paged media.
952 | */
953 |
954 | function atpage() {
955 | var pos = position();
956 | var m = match(/^@page */);
957 | if (!m) return;
958 |
959 | var sel = selector() || [];
960 |
961 | if (!open()) return error("@page missing '{'");
962 | var decls = comments();
963 |
964 | // declarations
965 | var decl;
966 | while (decl = declaration()) {
967 | decls.push(decl);
968 | decls = decls.concat(comments());
969 | }
970 |
971 | if (!close()) return error("@page missing '}'");
972 |
973 | return pos({
974 | type: 'page',
975 | selectors: sel,
976 | declarations: decls
977 | });
978 | }
979 |
980 | /**
981 | * Parse document.
982 | */
983 |
984 | function atdocument() {
985 | var pos = position();
986 | var m = match(/^@([-\w]+)?document *([^{]+)/);
987 | if (!m) return;
988 |
989 | var vendor = trim(m[1]);
990 | var doc = trim(m[2]);
991 |
992 | if (!open()) return error("@document missing '{'");
993 |
994 | var style = comments().concat(rules());
995 |
996 | if (!close()) return error("@document missing '}'");
997 |
998 | return pos({
999 | type: 'document',
1000 | document: doc,
1001 | vendor: vendor,
1002 | rules: style
1003 | });
1004 | }
1005 |
1006 | /**
1007 | * Parse import
1008 | */
1009 |
1010 | function atimport() {
1011 | return _atrule('import');
1012 | }
1013 |
1014 | /**
1015 | * Parse charset
1016 | */
1017 |
1018 | function atcharset() {
1019 | return _atrule('charset');
1020 | }
1021 |
1022 | /**
1023 | * Parse namespace
1024 | */
1025 |
1026 | function atnamespace() {
1027 | return _atrule('namespace')
1028 | }
1029 |
1030 | /**
1031 | * Parse non-block at-rules
1032 | */
1033 |
1034 | function _atrule(name) {
1035 | var pos = position();
1036 | var m = match(new RegExp('^@' + name + ' *([^;\\n]+);'));
1037 | if (!m) return;
1038 | var ret = { type: name };
1039 | ret[name] = trim(m[1]);
1040 | return pos(ret);
1041 | }
1042 |
1043 | /**
1044 | * Parse at rule.
1045 | */
1046 |
1047 | function atrule() {
1048 | if (css[0] != '@') return;
1049 |
1050 | return atkeyframes()
1051 | || atmedia()
1052 | || atsupports()
1053 | || atimport()
1054 | || atcharset()
1055 | || atnamespace()
1056 | || atdocument()
1057 | || atpage()
1058 | || athost();
1059 | }
1060 |
1061 | /**
1062 | * Parse rule.
1063 | */
1064 |
1065 | function rule() {
1066 | var pos = position();
1067 | var sel = selector();
1068 |
1069 | if (!sel) return;
1070 | comments();
1071 |
1072 | return pos({
1073 | type: 'rule',
1074 | selectors: sel,
1075 | declarations: declarations()
1076 | });
1077 | }
1078 |
1079 | return stylesheet();
1080 | };
1081 |
1082 | /**
1083 | * Trim `str`.
1084 | */
1085 |
1086 | function trim(str) {
1087 | return str ? str.replace(/^\s+|\s+$/g, '') : '';
1088 | }
1089 |
1090 | },{}],5:[function(require,module,exports){
1091 | // shim for using process in browser
1092 |
1093 | var process = module.exports = {};
1094 |
1095 | process.nextTick = (function () {
1096 | var canSetImmediate = typeof window !== 'undefined'
1097 | && window.setImmediate;
1098 | var canPost = typeof window !== 'undefined'
1099 | && window.postMessage && window.addEventListener
1100 | ;
1101 |
1102 | if (canSetImmediate) {
1103 | return function (f) { return window.setImmediate(f) };
1104 | }
1105 |
1106 | if (canPost) {
1107 | var queue = [];
1108 | window.addEventListener('message', function (ev) {
1109 | var source = ev.source;
1110 | if ((source === window || source === null) && ev.data === 'process-tick') {
1111 | ev.stopPropagation();
1112 | if (queue.length > 0) {
1113 | var fn = queue.shift();
1114 | fn();
1115 | }
1116 | }
1117 | }, true);
1118 |
1119 | return function nextTick(fn) {
1120 | queue.push(fn);
1121 | window.postMessage('process-tick', '*');
1122 | };
1123 | }
1124 |
1125 | return function nextTick(fn) {
1126 | setTimeout(fn, 0);
1127 | };
1128 | })();
1129 |
1130 | process.title = 'browser';
1131 | process.browser = true;
1132 | process.env = {};
1133 | process.argv = [];
1134 |
1135 | function noop() {}
1136 |
1137 | process.on = noop;
1138 | process.once = noop;
1139 | process.off = noop;
1140 | process.emit = noop;
1141 |
1142 | process.binding = function (name) {
1143 | throw new Error('process.binding is not supported');
1144 | }
1145 |
1146 | // TODO(shtylman)
1147 | process.cwd = function () { return '/' };
1148 | process.chdir = function (dir) {
1149 | throw new Error('process.chdir is not supported');
1150 | };
1151 |
1152 | },{}],6:[function(require,module,exports){
1153 | (function (process){
1154 | // vim:ts=4:sts=4:sw=4:
1155 | /*!
1156 | *
1157 | * Copyright 2009-2012 Kris Kowal under the terms of the MIT
1158 | * license found at http://github.com/kriskowal/q/raw/master/LICENSE
1159 | *
1160 | * With parts by Tyler Close
1161 | * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
1162 | * at http://www.opensource.org/licenses/mit-license.html
1163 | * Forked at ref_send.js version: 2009-05-11
1164 | *
1165 | * With parts by Mark Miller
1166 | * Copyright (C) 2011 Google Inc.
1167 | *
1168 | * Licensed under the Apache License, Version 2.0 (the "License");
1169 | * you may not use this file except in compliance with the License.
1170 | * You may obtain a copy of the License at
1171 | *
1172 | * http://www.apache.org/licenses/LICENSE-2.0
1173 | *
1174 | * Unless required by applicable law or agreed to in writing, software
1175 | * distributed under the License is distributed on an "AS IS" BASIS,
1176 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1177 | * See the License for the specific language governing permissions and
1178 | * limitations under the License.
1179 | *
1180 | */
1181 |
1182 | (function (definition) {
1183 | // Turn off strict mode for this function so we can assign to global.Q
1184 | /* jshint strict: false */
1185 |
1186 | // This file will function properly as a