├── .gitignore
├── LICENSE
├── MODULE.md
├── README.md
├── bower.json
├── examples
├── Backend
│ ├── Main.purs
│ └── main.html
├── Todomvc
│ ├── Controller.purs
│ ├── Escape.purs
│ ├── Focus.purs
│ ├── Main.purs
│ ├── Storage.purs
│ └── main.html
└── TodomvcF
│ ├── AppI.purs
│ ├── Escape.purs
│ ├── Focus.purs
│ ├── Main.purs
│ ├── StorageF.purs
│ ├── StorageI.purs
│ ├── ThisF.purs
│ ├── ThisI.purs
│ ├── TodomvcF.purs
│ ├── TodomvcI.purs
│ └── main.html
├── gulpfile.js
├── package.json
└── src
├── Angular.purs
└── Angular
├── Animate.purs
├── Attributes.purs
├── Cache.purs
├── DI.purs
├── Deferred.purs
├── Element.purs
├── FormController.purs
├── Http.purs
├── Http
├── Internal.purs
└── Types.purs
├── Injector.purs
├── Interpolate.purs
├── Interval.purs
├── Location.purs
├── Log.purs
├── Module.purs
├── NgModelController.purs
├── Parse.purs
├── Promise.purs
├── Q.purs
├── Scope.purs
├── This.purs
└── Timeout.purs
/.gitignore:
--------------------------------------------------------------------------------
1 | .psci
2 | node_modules
3 | bower_components
4 | js
5 | externs
6 | dist
7 | output
8 | tmp
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Eric Thul
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a
4 | copy of this software and associated documentation files (the
5 | "Software"), in the Software without restriction, including without
6 | limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to
8 | whom the Software is furnished to do so, subject to the following
9 | conditions:
10 |
11 | The above copyright notice and this permission notice shall be included
12 | in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/MODULE.md:
--------------------------------------------------------------------------------
1 | # Module Documentation
2 |
3 | ## Module Angular
4 |
5 | ### Values
6 |
7 | bootstrap :: forall e. Element -> [String] -> Eff e Injector
8 |
9 | copy :: forall e a. a -> Eff e a
10 |
11 | extend :: forall e a b c. { | a } -> { | b } -> Eff e { | c }
12 |
13 |
14 | ## Module Angular.Animate
15 |
16 | ### Types
17 |
18 | data Animate :: *
19 |
20 | type AnimateEff e = Eff (nganimate :: NgAnimate | e) Unit
21 |
22 | data NgAnimate :: !
23 |
24 |
25 | ### Values
26 |
27 | addClass :: forall e f r. Element -> String -> Maybe (Eff f r) -> Animate -> AnimateEff e
28 |
29 | enter :: forall e f r. Element -> Element -> Element -> Maybe (Eff f r) -> Animate -> AnimateEff e
30 |
31 | leave :: forall e f r. Element -> Maybe (Eff f r) -> Animate -> AnimateEff e
32 |
33 | move :: forall e f r. Element -> Element -> Element -> Maybe (Eff f r) -> Animate -> AnimateEff e
34 |
35 | removeClass :: forall e f r. Element -> String -> Maybe (Eff f r) -> Animate -> AnimateEff e
36 |
37 | setClass :: forall e f r. Element -> String -> String -> Maybe (Eff f r) -> Animate -> AnimateEff e
38 |
39 |
40 | ## Module Angular.Attributes
41 |
42 | ### Types
43 |
44 | type AttrEff e r = Eff (ngattr :: NgAttr | e) r
45 |
46 | data Attributes :: *
47 |
48 | data NgAttr :: !
49 |
50 |
51 | ### Values
52 |
53 | addClass :: forall e. String -> Attributes -> AttrEff e Unit
54 |
55 | attr :: forall e a. Attributes -> AttrEff e { | a }
56 |
57 | get :: forall e a. Attributes -> AttrEff e { | a }
58 |
59 | observe :: forall e f. String -> (String -> Eff f Unit) -> Attributes -> AttrEff e Unit
60 |
61 | removeClass :: forall e. String -> Attributes -> AttrEff e Unit
62 |
63 | set :: forall e. String -> String -> Attributes -> AttrEff e Unit
64 |
65 | updateClass :: forall e. String -> String -> Attributes -> AttrEff e Unit
66 |
67 |
68 | ## Module Angular.Cache
69 |
70 | ### Types
71 |
72 | data Cache :: *
73 |
74 | type CacheEff e r = Eff (ngcache :: NgCache | e) r
75 |
76 | data CacheFactory :: *
77 |
78 | type Key = String
79 |
80 | type Name = String
81 |
82 | data NgCache :: !
83 |
84 | type Options a = { capacity :: Number | a }
85 |
86 |
87 | ### Values
88 |
89 | cache :: forall e a. Name -> Maybe (Options a) -> CacheFactory -> CacheEff e Cache
90 |
91 | destroy :: forall e. Cache -> CacheEff e Unit
92 |
93 | get :: forall e a. Key -> Cache -> CacheEff e a
94 |
95 | info :: forall e a. Cache -> CacheEff e { size :: Number, id :: String | a }
96 |
97 | put :: forall e a. Key -> a -> Cache -> CacheEff e a
98 |
99 | remove :: forall e. Key -> Cache -> CacheEff e Unit
100 |
101 | removeAll :: forall e. Cache -> CacheEff e Unit
102 |
103 |
104 | ## Module Angular.DI
105 |
106 | ### Types
107 |
108 | data Annotated :: * -> *
109 |
110 | newtype RootElement where
111 | RootElement :: Element -> RootElement
112 |
113 | newtype RootScope a where
114 | RootScope :: Scope a -> RootScope a
115 |
116 |
117 | ### Type Classes
118 |
119 | class Dependency a where
120 | name :: String
121 |
122 | class Injectable a where
123 | dependencies :: a -> [String]
124 |
125 | class (Dependency a) <= Service a where
126 |
127 |
128 | ### Type Class Instances
129 |
130 | instance dependencyAnimate :: Dependency Animate
131 |
132 | instance dependencyAttributes :: Dependency Attributes
133 |
134 | instance dependencyCacheFactory :: Dependency CacheFactory
135 |
136 | instance dependencyElement :: Dependency Element
137 |
138 | instance dependencyHttp :: Dependency Http
139 |
140 | instance dependencyInjector :: Dependency Injector
141 |
142 | instance dependencyInterpolate :: Dependency Interpolate
143 |
144 | instance dependencyInterval :: Dependency Interval
145 |
146 | instance dependencyLocation :: Dependency Location
147 |
148 | instance dependencyLog :: Dependency Log
149 |
150 | instance dependencyParse :: Dependency Parse
151 |
152 | instance dependencyQ :: Dependency Q
153 |
154 | instance dependencyRootElement :: Dependency RootElement
155 |
156 | instance dependencyRootScope :: Dependency (RootScope a)
157 |
158 | instance dependencyScope :: Dependency (Scope a)
159 |
160 | instance dependencyThis :: Dependency (This a)
161 |
162 | instance dependencyTimeout :: Dependency Timeout
163 |
164 | instance injectableEff :: Injectable (Eff e r)
165 |
166 | instance injectableFn :: (Dependency a, Injectable b) => Injectable (a -> b)
167 |
168 | instance serviceAnimate :: Service Animate
169 |
170 | instance serviceCacheFactory :: Service CacheFactory
171 |
172 | instance serviceHttp :: Service Http
173 |
174 | instance serviceInjector :: Service Injector
175 |
176 | instance serviceInterpolate :: Service Interpolate
177 |
178 | instance serviceInterval :: Service Interval
179 |
180 | instance serviceLocation :: Service Location
181 |
182 | instance serviceLog :: Service Log
183 |
184 | instance serviceParse :: Service Parse
185 |
186 | instance serviceQ :: Service Q
187 |
188 | instance serviceRootElement :: Service RootElement
189 |
190 | instance serviceRootScope :: Service (RootScope a)
191 |
192 | instance serviceTimeout :: Service Timeout
193 |
194 |
195 | ### Values
196 |
197 | annotate :: forall a. (Injectable a) => a -> Annotated a
198 |
199 | get :: forall e a. (Service a) => Injector -> InjEff e a
200 |
201 |
202 | ## Module Angular.Deferred
203 |
204 | ### Types
205 |
206 | data Deferred :: * -> * -> *
207 |
208 | type DeferredEff e r = Eff (ngdeferred :: NgDeferred | e) r
209 |
210 | data NgDeferred :: !
211 |
212 |
213 | ### Values
214 |
215 | notify :: forall e s a b. s -> Deferred a b -> DeferredEff e Unit
216 |
217 | promise :: forall e a b. Deferred a b -> DeferredEff e (Promise a b)
218 |
219 | reject :: forall e a b. a -> Deferred a b -> DeferredEff e Unit
220 |
221 | resolve :: forall e a b. b -> Deferred a b -> DeferredEff e Unit
222 |
223 |
224 | ## Module Angular.Element
225 |
226 | ### Types
227 |
228 | data DeregisterHandler :: # ! -> *
229 |
230 | type ElEff e r = Eff (ngel :: NgEl | e) r
231 |
232 | data Element :: *
233 |
234 | type Handler e = DOMEvent -> Eff e Unit
235 |
236 | data NgEl :: !
237 |
238 |
239 | ### Values
240 |
241 | (!!) :: Element -> Number -> Maybe HTMLElement
242 |
243 | addClass :: forall e. String -> Element -> ElEff e Element
244 |
245 | after :: forall e. Element -> Element -> ElEff e Element
246 |
247 | bind :: forall e f. String -> Handler f -> Element -> ElEff e (DeregisterHandler f)
248 |
249 | children :: forall e. Element -> ElEff e Element
250 |
251 | clone :: forall e. Element -> ElEff e Element
252 |
253 | contents :: forall e. Element -> ElEff e Element
254 |
255 | controller :: forall e a. Maybe String -> Element -> ElEff e (Maybe a)
256 |
257 | element :: forall e. String -> ElEff e Element
258 |
259 | empty :: forall e. Element -> ElEff e Element
260 |
261 | eq :: forall e. Number -> Element -> ElEff e Element
262 |
263 | find :: forall e. Number -> Element -> ElEff e Element
264 |
265 | getAttr :: forall e. String -> Element -> ElEff e (Maybe String)
266 |
267 | getCss :: forall e. String -> Element -> ElEff e (Maybe String)
268 |
269 | getData :: forall e a. String -> Element -> ElEff e (Maybe a)
270 |
271 | getProp :: forall e. String -> Element -> ElEff e (Maybe String)
272 |
273 | getVal :: forall e. Element -> ElEff e (Maybe String)
274 |
275 | hasClass :: forall e. String -> Element -> ElEff e Boolean
276 |
277 | html :: forall e. Element -> ElEff e String
278 |
279 | inheritedData :: forall e a. Element -> ElEff e { | a }
280 |
281 | injector :: forall e a. Element -> ElEff e (Maybe Injector)
282 |
283 | isolateScope :: forall e a. Element -> ElEff e (Maybe (Scope a))
284 |
285 | next :: forall e. Element -> ElEff e Element
286 |
287 | off :: forall e f. String -> Element -> ElEff e Element
288 |
289 | offHandler :: forall e f. String -> DeregisterHandler f -> Element -> ElEff e Element
290 |
291 | on :: forall e f. String -> Handler f -> Element -> ElEff e (DeregisterHandler f)
292 |
293 | one :: forall e f. String -> Handler f -> Element -> ElEff e (DeregisterHandler f)
294 |
295 | parent :: forall e. Element -> ElEff e Element
296 |
297 | prepend :: forall e. Element -> Element -> ElEff e Element
298 |
299 | ready :: forall e. Eff e Unit -> Element -> ElEff e Element
300 |
301 | remove :: forall e. Element -> ElEff e Element
302 |
303 | removeAttr :: forall e. String -> Element -> ElEff e Element
304 |
305 | removeClass :: forall e. String -> Element -> ElEff e Element
306 |
307 | removeData :: forall e. String -> Element -> ElEff e Element
308 |
309 | replaceWith :: forall e. Element -> Element -> ElEff e Element
310 |
311 | scope :: forall e a. Element -> ElEff e (Maybe (Scope a))
312 |
313 | setAllAttr :: forall e a. { | a } -> Element -> ElEff e Element
314 |
315 | setAllCss :: forall e a. { | a } -> Element -> ElEff e Element
316 |
317 | setAllData :: forall e a. { | a } -> Element -> ElEff e Element
318 |
319 | setAllProp :: forall e a. { | a } -> Element -> ElEff e Element
320 |
321 | setAttr :: forall e. String -> String -> Element -> ElEff e Element
322 |
323 | setCss :: forall e. String -> String -> Element -> ElEff e Element
324 |
325 | setData :: forall e a. String -> a -> Element -> ElEff e Element
326 |
327 | setProp :: forall e. String -> String -> Element -> ElEff e Element
328 |
329 | setVal :: forall e. String -> Element -> ElEff e Element
330 |
331 | toggleClass :: forall e. String -> Boolean -> Element -> ElEff e Element
332 |
333 | triggerHandler :: forall e a. String -> [a] -> Element -> ElEff e Element
334 |
335 | unbind :: forall e f. String -> Element -> ElEff e Element
336 |
337 | unbindHandler :: forall e f. String -> DeregisterHandler f -> Element -> ElEff e Element
338 |
339 | wrap :: forall e. Element -> Element -> ElEff e Element
340 |
341 |
342 | ## Module Angular.FormController
343 |
344 | ### Types
345 |
346 | data FormController :: *
347 |
348 | type FormEff e r = Eff (ngform :: NgForm | e) r
349 |
350 | data NgForm :: !
351 |
352 |
353 | ### Values
354 |
355 | addControl :: forall e a. NgModelController a -> FormController -> FormEff e Unit
356 |
357 | dirty :: forall e. FormController -> FormEff e Boolean
358 |
359 | error :: forall e a. FormController -> FormEff e { | a }
360 |
361 | invalid :: forall e. FormController -> FormEff e Boolean
362 |
363 | pristine :: forall e. FormController -> FormEff e Boolean
364 |
365 | removeControl :: forall e a. NgModelController a -> FormController -> FormEff e Unit
366 |
367 | setDirty :: forall e. FormController -> FormEff e Unit
368 |
369 | setPristine :: forall e. FormController -> FormEff e Unit
370 |
371 | setValidity :: forall e a. ValidationErrorKey -> Boolean -> NgModelController a -> FormController -> FormEff e Unit
372 |
373 | valid :: forall e. FormController -> FormEff e Boolean
374 |
375 |
376 | ## Module Angular.Http
377 |
378 | ### Types
379 |
380 | type Config a b c d = { responseType :: D.ResponseType, withCredentials :: Boolean, timeout :: Either Number (Promise c d), cache :: Either Boolean Cache, xsrfCookieName :: String, xsrfHeaderName :: String, headers :: Headers, "data" :: RequestData b, params :: { | a }, url :: D.Url, method :: D.HttpMethod }
381 |
382 | data Http :: *
383 |
384 | type HttpResponse e r a b c d = HttpEff e (Promise I.ForeignResponse (Response r a b c d))
385 |
386 | type Response r a b c d = { statusText :: String, config :: Config a b c d, headers :: [String] -> String, status :: Status, "data" :: D.HttpData r }
387 |
388 |
389 | ### Values
390 |
391 | config :: forall a b c d. Config a b c d
392 |
393 | del :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
394 |
395 | del' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
396 |
397 | get :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
398 |
399 | get' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
400 |
401 | head :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
402 |
403 | head' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
404 |
405 | http :: forall e r a b c d. Config a b c d -> Http -> HttpResponse e r a b c d
406 |
407 | jsonp :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
408 |
409 | jsonp' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
410 |
411 | post :: forall e r a b c d. D.Url -> RequestData b -> Http -> HttpResponse e r a b c d
412 |
413 | post' :: forall e r a b c d. D.Url -> RequestData b -> Config a b c d -> Http -> HttpResponse e r a b c d
414 |
415 | put :: forall e r a b c d. D.Url -> RequestData b -> Http -> HttpResponse e r a b c d
416 |
417 | put' :: forall e r a b c d. D.Url -> RequestData b -> Config a b c d -> Http -> HttpResponse e r a b c d
418 |
419 |
420 | ## Module Angular.Injector
421 |
422 | ### Types
423 |
424 | type InjEff e a = Eff (nginj :: NgInj | e) a
425 |
426 | data Injector :: *
427 |
428 | data NgInj :: !
429 |
430 |
431 | ### Values
432 |
433 | annotate :: forall e a. a -> Injector -> InjEff e [String]
434 |
435 | get :: forall e a. String -> Injector -> InjEff e a
436 |
437 | has :: forall e. String -> Injector -> InjEff e Boolean
438 |
439 | injector :: forall e. [String] -> InjEff e Injector
440 |
441 | instantiate :: forall e r a b. a -> Maybe { | b } -> Injector -> InjEff e r
442 |
443 | invoke :: forall e r a b c. a -> Maybe { | b } -> Maybe { | c } -> Injector -> InjEff e r
444 |
445 |
446 | ## Module Angular.Interpolate
447 |
448 | ### Types
449 |
450 | type Expression a = { | a } -> String
451 |
452 | data Interpolate :: *
453 |
454 | type InterpolateEff e a = Eff (nginterpolate :: NgInterpolate | e) a
455 |
456 | data NgInterpolate :: !
457 |
458 |
459 | ### Values
460 |
461 | endSymbol :: Interpolate -> String
462 |
463 | interpolate :: forall e a. String -> Maybe Boolean -> Maybe String -> Interpolate -> InterpolateEff e (Expression a)
464 |
465 | startSymbol :: Interpolate -> String
466 |
467 |
468 | ## Module Angular.Interval
469 |
470 | ### Types
471 |
472 | data Interval :: *
473 |
474 | type IntervalEff e r = Eff (nginterval :: NgInterval | e) r
475 |
476 | type IntervalPromise = Promise Unit Number
477 |
478 | data NgInterval :: !
479 |
480 |
481 | ### Values
482 |
483 | cancel :: forall e. IntervalPromise -> Interval -> IntervalEff e Boolean
484 |
485 | interval :: forall e f r. Eff f r -> Number -> Number -> Boolean -> Interval -> IntervalEff e IntervalPromise
486 |
487 | interval' :: forall e f r. Eff f r -> Number -> Number -> Interval -> IntervalEff e IntervalPromise
488 |
489 | interval'' :: forall e f r. Eff f r -> Number -> Interval -> IntervalEff e IntervalPromise
490 |
491 | intervalk :: forall e f r. Number -> Number -> Boolean -> Interval -> Eff f r -> IntervalEff e IntervalPromise
492 |
493 |
494 | ## Module Angular.Location
495 |
496 | ### Types
497 |
498 | type LocEff e a = Eff (ngloc :: NgLoc | e) a
499 |
500 | data Location :: *
501 |
502 | data NgLoc :: !
503 |
504 |
505 | ### Values
506 |
507 | getPath :: forall e. Location -> LocEff e String
508 |
509 | setPath :: forall e. String -> Location -> LocEff e String
510 |
511 |
512 | ## Module Angular.Log
513 |
514 | ### Types
515 |
516 | data Log :: *
517 |
518 | type LogEff e = Eff (nglog :: NgLog | e) Unit
519 |
520 | data NgLog :: !
521 |
522 |
523 | ### Values
524 |
525 | debug :: forall e a. a -> Log -> LogEff e
526 |
527 | error :: forall e a. a -> Log -> LogEff e
528 |
529 | info :: forall e a. a -> Log -> LogEff e
530 |
531 | log :: forall e a. a -> Log -> LogEff e
532 |
533 | warn :: forall e a. a -> Log -> LogEff e
534 |
535 |
536 | ## Module Angular.Module
537 |
538 | ### Types
539 |
540 | data Module :: *
541 |
542 | data NgReadModule :: !
543 |
544 | data NgRegisterToModule :: !
545 |
546 | data NgWriteModule :: !
547 |
548 | type ReadEff e = Eff (ngrmod :: NgReadModule | e) Module
549 |
550 | type RegisterEff e = Eff (nggmod :: NgRegisterToModule | e) Module
551 |
552 | type WriteEff e = Eff (ngwmod :: NgWriteModule | e) Module
553 |
554 |
555 | ### Values
556 |
557 | animation :: forall e a. String -> a -> Module -> RegisterEff e
558 |
559 | config :: forall e a. a -> Module -> RegisterEff e
560 |
561 | constant :: forall e a. String -> a -> Module -> RegisterEff e
562 |
563 | controller :: forall e a. String -> a -> Module -> RegisterEff e
564 |
565 | directive :: forall e a. String -> a -> Module -> RegisterEff e
566 |
567 | factory :: forall e a. String -> a -> Module -> RegisterEff e
568 |
569 | filter :: forall e a. String -> a -> Module -> RegisterEff e
570 |
571 | ngmodule :: forall e. String -> ReadEff e
572 |
573 | ngmodule' :: forall e. String -> [String] -> WriteEff e
574 |
575 | provider :: forall e a. String -> a -> Module -> RegisterEff e
576 |
577 | run :: forall e a. a -> Module -> RegisterEff e
578 |
579 | service :: forall e a. String -> a -> Module -> RegisterEff e
580 |
581 | value :: forall e a. String -> a -> Module -> RegisterEff e
582 |
583 |
584 | ## Module Angular.NgModelController
585 |
586 | ### Types
587 |
588 | type Formatter a = a -> String
589 |
590 | data NgModel :: !
591 |
592 | data NgModelController :: * -> *
593 |
594 | type NgModelEff e r = Eff (ngmodel :: NgModel | e) r
595 |
596 | type Parser a = String -> Maybe a
597 |
598 | type ValidationErrorKey = String
599 |
600 |
601 | ### Values
602 |
603 | appendFormatters :: forall e a. [Formatter a] -> NgModelController a -> NgModelEff e Unit
604 |
605 | appendParsers :: forall e a. [Parser a] -> NgModelController a -> NgModelEff e Unit
606 |
607 | appendViewChangeListeners :: forall e a. [Eff e Unit] -> NgModelController a -> NgModelEff e Unit
608 |
609 | dirty :: forall e a. NgModelController a -> NgModelEff e Boolean
610 |
611 | error :: forall e a b. NgModelController a -> NgModelEff e { | b }
612 |
613 | invalid :: forall e a. NgModelController a -> NgModelEff e Boolean
614 |
615 | isEmpty :: forall e a. a -> NgModelController a -> NgModelEff e Boolean
616 |
617 | modelValue :: forall e a. NgModelController a -> NgModelEff e a
618 |
619 | prependFormatters :: forall e a. [Formatter a] -> NgModelController a -> NgModelEff e Unit
620 |
621 | prependParsers :: forall e a. [Parser a] -> NgModelController a -> NgModelEff e Unit
622 |
623 | prependViewChangeListeners :: forall e a. [Eff e Unit] -> NgModelController a -> NgModelEff e Unit
624 |
625 | pristine :: forall e a. NgModelController a -> NgModelEff e Boolean
626 |
627 | render :: forall e a. NgModelController a -> NgModelEff e Unit
628 |
629 | setIsEmpty :: forall e a b. (b -> NgModelEff e Boolean) -> NgModelController a -> NgModelEff e (NgModelController b)
630 |
631 | setModelValue :: forall e a b. b -> NgModelController a -> NgModelEff e (NgModelController b)
632 |
633 | setPristine :: forall e a. NgModelController a -> NgModelEff e Unit
634 |
635 | setRender :: forall e a. NgModelEff e Unit -> NgModelController a -> NgModelEff e Unit
636 |
637 | setValidity :: forall e a. ValidationErrorKey -> Boolean -> NgModelController a -> NgModelEff e Unit
638 |
639 | setViewValue :: forall e a. String -> NgModelController a -> NgModelEff e Unit
640 |
641 | valid :: forall e a. NgModelController a -> NgModelEff e Boolean
642 |
643 | viewValue :: forall e a. NgModelController a -> NgModelEff e String
644 |
645 |
646 | ## Module Angular.Parse
647 |
648 | ### Types
649 |
650 | type Expression = String
651 |
652 | data Getter :: * -> *
653 |
654 | data NgParse :: !
655 |
656 | data Parse :: *
657 |
658 | type ParseEff e r = Eff (ngparse :: NgParse | e) r
659 |
660 | data Setter :: * -> *
661 |
662 |
663 | ### Values
664 |
665 | assign :: forall a. Getter a -> Maybe (Setter a)
666 |
667 | constant :: forall a. Getter a -> Boolean
668 |
669 | get :: forall e a b c. { | a } -> { | b } -> Getter c -> ParseEff e c
670 |
671 | literal :: forall a. Getter a -> Boolean
672 |
673 | parse :: forall e a. Expression -> Parse -> ParseEff e (Getter a)
674 |
675 | set :: forall e a b. { | a } -> b -> Setter b -> ParseEff e b
676 |
677 |
678 | ## Module Angular.Promise
679 |
680 | ### Types
681 |
682 | data Promise :: * -> * -> *
683 |
684 | type PromiseEC e a b = ErrorT a (ContT Unit (Eff e)) b
685 |
686 |
687 | ### Values
688 |
689 | catch :: forall a b c d. (a -> Promise c d) -> Promise a b -> Promise c d
690 |
691 | finally :: forall e r a b. Eff e r -> Promise a b -> Promise a b
692 |
693 | liftPromiseEC :: forall e a b. (Error a) => Eff e (Promise a b) -> PromiseEC e a b
694 |
695 | runPromiseEC :: forall e a b. PromiseEC e a b -> (Either a b -> Eff e Unit) -> Eff e Unit
696 |
697 | then1 :: forall a b c. (b -> Promise a c) -> Promise a b -> Promise a c
698 |
699 | then1' :: forall a b c. (b -> c) -> Promise a b -> Promise a c
700 |
701 | then2 :: forall a b c d. (b -> Promise c d) -> (a -> Promise c d) -> Promise a b -> Promise c d
702 |
703 | then2' :: forall a b c d. (b -> d) -> (a -> c) -> Promise a b -> Promise c d
704 |
705 | then3 :: forall e s t a b c d. (b -> Promise c d) -> (a -> Promise c d) -> (s -> Eff e t) -> Promise a b -> Promise c d
706 |
707 | then3' :: forall e s t a b c d. (b -> d) -> (a -> c) -> (s -> Eff e t) -> Promise a b -> Promise c d
708 |
709 |
710 | ## Module Angular.Q
711 |
712 | ### Types
713 |
714 | data NgQ :: !
715 |
716 | data Q :: *
717 |
718 | type QEff e r = Eff (ngq :: NgQ | e) r
719 |
720 |
721 | ### Values
722 |
723 | all :: forall e a b. [Promise a b] -> Q -> QEff e (Promise b [a])
724 |
725 | defer :: forall e a b. Q -> QEff e (Deferred a b)
726 |
727 | reject :: forall e a b. a -> Q -> QEff e (Promise a b)
728 |
729 | when :: forall e a b. b -> Q -> QEff e (Promise a b)
730 |
731 |
732 | ## Module Angular.Scope
733 |
734 | ### Types
735 |
736 | data ApplyExpr e r a where
737 | DefaultApplyExpr :: ApplyExpr e r a
738 | StringApplyExpr :: String -> ApplyExpr e r a
739 | FnApplyExpr :: (Scope a -> Eff e r) -> ApplyExpr e r a
740 |
741 | type Event e a b = { defaultPrevented :: Boolean, preventDefault :: Eff e Unit, stopPropagation :: Eff e Unit, name :: String, currentScope :: Scope b, targetScope :: Scope a }
742 |
743 | data NgReadScope :: !
744 |
745 | data NgScope :: !
746 |
747 | data NgWriteScope :: !
748 |
749 | data OnDeregistration :: *
750 |
751 | type ReadEff e a = Eff (ngrscope :: NgReadScope | e) { | a }
752 |
753 | type ReadWriteEff e r = Eff (ngwscope :: NgWriteScope, ngrscope :: NgReadScope | e) r
754 |
755 | data Scope :: # * -> *
756 |
757 | type ScopeEff e r = Eff (ngscope :: NgScope | e) r
758 |
759 | data WatchDeregistration :: *
760 |
761 | type WatchListener e a b = a -> a -> Scope b -> Eff e Unit
762 |
763 | type WriteEff e = Eff (ngwscope :: NgWriteScope | e) Unit
764 |
765 |
766 | ### Values
767 |
768 | apply :: forall e r a. ApplyExpr e r a -> Scope a -> ScopeEff e r
769 |
770 | applyExpr :: forall e r a. (Scope a -> Eff e r) -> ApplyExpr e r a
771 |
772 | broadcast :: forall e a b c. String -> a -> Scope b -> ScopeEff e (Event e b c)
773 |
774 | defaultApplyExpr :: forall e r a. ApplyExpr e r a
775 |
776 | deregisterOn :: OnDeregistration -> Unit
777 |
778 | deregisterWatch :: WatchDeregistration -> Unit
779 |
780 | destroy :: forall e a. Scope a -> ScopeEff e Unit
781 |
782 | digest :: forall e a. Scope a -> ScopeEff e Unit
783 |
784 | emit :: forall e a b c. String -> a -> Scope b -> ScopeEff e (Event e b c)
785 |
786 | evalAsync :: forall e r a. Maybe (Scope a -> Eff e r) -> Scope a -> ScopeEff e r
787 |
788 | evalSync :: forall e r a b. Maybe (Scope a -> Eff e r) -> Maybe { | b } -> Scope a -> ScopeEff e r
789 |
790 | extendScope :: forall e a b. { | b } -> Scope a -> WriteEff e
791 |
792 | id :: forall a. Scope a -> String
793 |
794 | modifyScope :: forall e a b. ({ | a } -> ReadWriteEff e { | b }) -> Scope a -> ReadWriteEff e Unit
795 |
796 | newScope :: forall e a b. Boolean -> Scope a -> ScopeEff e (Scope b)
797 |
798 | on :: forall e a b c. String -> (Event e a b -> c -> Eff e Unit) -> Scope b -> ScopeEff e OnDeregistration
799 |
800 | parent :: forall a b. Scope a -> Maybe (Scope b)
801 |
802 | readScope :: forall e a. Scope a -> ReadEff e a
803 |
804 | root :: forall a b. Scope a -> Scope b
805 |
806 | stringApplyExpr :: forall e r a. String -> ApplyExpr e r a
807 |
808 | watch :: forall e a b. String -> Maybe (WatchListener e a b) -> Boolean -> Scope b -> ScopeEff e WatchDeregistration
809 |
810 | watchCollection :: forall e a b. String -> WatchListener e a b -> Scope b -> ScopeEff e WatchDeregistration
811 |
812 | writeScope :: forall e a b. String -> b -> Scope a -> WriteEff e
813 |
814 |
815 | ## Module Angular.This
816 |
817 | ### Types
818 |
819 | data NgReadThis :: !
820 |
821 | data NgWriteThis :: !
822 |
823 | type ReadEff e a = Eff (ngrthis :: NgReadThis | e) { | a }
824 |
825 | type ReadWriteEff e r = Eff (ngwthis :: NgWriteThis, ngrthis :: NgReadThis | e) r
826 |
827 | data This :: # * -> *
828 |
829 | type WriteEff e = Eff (ngwthis :: NgWriteThis | e) Unit
830 |
831 |
832 | ### Values
833 |
834 | extendThis :: forall e a b. { | b } -> This a -> WriteEff e
835 |
836 | modifyThis :: forall e a b. ({ | a } -> ReadWriteEff e { | b }) -> This a -> ReadWriteEff e Unit
837 |
838 | readThis :: forall e a. This a -> ReadEff e a
839 |
840 | writeThis :: forall e a b. String -> b -> This a -> WriteEff e
841 |
842 |
843 | ## Module Angular.Timeout
844 |
845 | ### Types
846 |
847 | data NgTimeout :: !
848 |
849 | data Timeout :: *
850 |
851 | type TimeoutEff e r = Eff (ngtimeout :: NgTimeout | e) r
852 |
853 | type TimeoutPromise a = Promise Error a
854 |
855 |
856 | ### Values
857 |
858 | cancel :: forall e r. TimeoutPromise r -> Timeout -> TimeoutEff e Boolean
859 |
860 | timeout :: forall e f r. Eff f r -> Number -> Boolean -> Timeout -> TimeoutEff e (TimeoutPromise r)
861 |
862 | timeout' :: forall e f r. Eff f r -> Number -> Timeout -> TimeoutEff e (TimeoutPromise r)
863 |
864 | timeout'' :: forall e f r. Eff f r -> Timeout -> TimeoutEff e (TimeoutPromise r)
865 |
866 | timeoutk :: forall e f r. Number -> Boolean -> Timeout -> Eff f r -> TimeoutEff e (TimeoutPromise r)
867 |
868 |
869 | ## Module Angular.Http.Internal
870 |
871 | ### Types
872 |
873 | data ForeignConfig :: *
874 |
875 | data ForeignResponse :: *
876 |
877 |
878 | ### Type Class Instances
879 |
880 | instance errorForeignResponse :: Error ForeignResponse
881 |
882 |
883 | ### Values
884 |
885 | foreignConfig :: forall e. HttpEff e ForeignConfig
886 |
887 | getConfigCache :: ForeignConfig -> Either Boolean Cache
888 |
889 | getConfigHeaders :: ForeignConfig -> Headers
890 |
891 | getConfigMethod :: ForeignConfig -> D.HttpMethod
892 |
893 | getConfigParams :: forall a. ForeignConfig -> { | a }
894 |
895 | getConfigRequestData :: forall e a. ForeignConfig -> RequestData a
896 |
897 | getConfigResponseType :: ForeignConfig -> D.ResponseType
898 |
899 | getConfigTimeout :: forall a b. ForeignConfig -> Either Number (Promise a b)
900 |
901 | getConfigUrl :: ForeignConfig -> D.Url
902 |
903 | getConfigWithCredentials :: ForeignConfig -> Boolean
904 |
905 | getConfigXsrfCookieName :: ForeignConfig -> String
906 |
907 | getConfigXsrfHeaderName :: ForeignConfig -> String
908 |
909 | getResponseConfig :: ForeignResponse -> ForeignConfig
910 |
911 | getResponseData :: forall a. D.ResponseType -> ForeignResponse -> D.HttpData a
912 |
913 | getResponseHeaders :: ForeignResponse -> [String] -> String
914 |
915 | getResponseStatus :: ForeignResponse -> Status
916 |
917 | getResponseStatusText :: ForeignResponse -> String
918 |
919 | setConfigCache :: forall e. Either Boolean Cache -> ForeignConfig -> HttpEff e Unit
920 |
921 | setConfigHeaders :: forall e. Headers -> ForeignConfig -> HttpEff e Unit
922 |
923 | setConfigMethod :: forall e. D.HttpMethod -> ForeignConfig -> HttpEff e Unit
924 |
925 | setConfigParams :: forall e a. { | a } -> ForeignConfig -> HttpEff e Unit
926 |
927 | setConfigRequestData :: forall e a. RequestData a -> ForeignConfig -> HttpEff e Unit
928 |
929 | setConfigResponseType :: forall e. D.ResponseType -> ForeignConfig -> HttpEff e Unit
930 |
931 | setConfigTimeout :: forall e a b. Either Number (Promise a b) -> ForeignConfig -> HttpEff e Unit
932 |
933 | setConfigUrl :: forall e. D.Url -> ForeignConfig -> HttpEff e Unit
934 |
935 | setConfigWithCredentials :: forall e. Boolean -> ForeignConfig -> HttpEff e Unit
936 |
937 | setConfigXsrfCookieName :: forall e. String -> ForeignConfig -> HttpEff e Unit
938 |
939 | setConfigXsrfHeaderName :: forall e. String -> ForeignConfig -> HttpEff e Unit
940 |
941 |
942 | ## Module Angular.Http.Types
943 |
944 | ### Types
945 |
946 | data ForeignCache :: *
947 |
948 | data ForeignHeaders :: *
949 |
950 | data ForeignRequestData :: *
951 |
952 | data ForeignResponseData :: *
953 |
954 | data ForeignTimeout :: *
955 |
956 | type Header = Tuple String (Either String (Unit -> String))
957 |
958 | newtype Headers where
959 | Headers :: [Header] -> Headers
960 |
961 | type HttpEff e r = Eff (nghttp :: NgHttp | e) r
962 |
963 | data NgHttp :: !
964 |
965 | data RequestData a where
966 | NoRequestData :: RequestData a
967 | StringRequestData :: String -> RequestData a
968 | ObjectRequestData :: a -> RequestData a
969 |
970 | type RequestDataFn a = { objectRequestData :: a -> RequestData a, stringRequestData :: String -> RequestData a, noRequestData :: RequestData a }
971 |
972 | data Status where
973 | OK :: Status
974 | Created :: Status
975 | NoContent :: Status
976 | BadRequest :: Status
977 | Unauthorized :: Status
978 | Forbidden :: Status
979 | NotFound :: Status
980 | InternalServerError :: Status
981 | OtherStatus :: Number -> Status
982 |
983 |
984 | ### Values
985 |
986 | cataRequestData :: forall a b. b -> (String -> b) -> (a -> b) -> RequestData a -> b
987 |
988 | fnHeader :: String -> (Unit -> String) -> Header
989 |
990 | readCacheFn :: Fn3 (Boolean -> Either Boolean Cache) (Cache -> Either Boolean Cache) ForeignCache (Either Boolean Cache)
991 |
992 | readHeadersFn :: forall a b. Fn4 (String -> Either String (Unit -> String)) ((Unit -> String) -> Either String (Unit -> String)) (String -> Either String (Unit -> String) -> Header) ForeignHeaders Headers
993 |
994 | readMethod :: String -> D.HttpMethod
995 |
996 | readRequestDataFn :: forall a. Fn2 (RequestDataFn a) ForeignRequestData (RequestData a)
997 |
998 | readResponseData :: forall a d. (d -> D.HttpData a) -> ForeignResponseData -> D.HttpData a
999 |
1000 | readResponseType :: String -> D.ResponseType
1001 |
1002 | readStatus :: Number -> Status
1003 |
1004 | readTimeoutFn :: forall a b. Fn3 (Number -> Either Number (Promise a b)) (Promise a b -> Either Number (Promise a b)) ForeignTimeout (Either Number (Promise a b))
1005 |
1006 | stringHeader :: String -> String -> Header
1007 |
1008 | writeRequestData :: forall a. RequestData a -> ForeignRequestData
1009 |
1010 |
1011 |
1012 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # purescript-angular
2 |
3 | [AngularJS 1.2 bindings](MODULE.md) for PureScript.
4 |
5 | **NOTICE**: This module is currently in the experimental stage.
6 |
7 | ## Examples
8 |
9 | ### todomvc
10 |
11 | The [todomvc](http://todomvc.com/architecture-examples/angularjs) has been implemented as an example. The example may be run as follows.
12 |
13 | ```bash
14 | purescript-angular $ npm install
15 |
16 | purescript-angular $ bower install
17 |
18 | purescript-angular $ gulp todomvc
19 |
20 | purescript-angular $ gulp watch.todomvc
21 | ```
22 |
23 | Then visit: [http://localhost:9501/examples/Todomvc/main.html](http://localhost:9501/examples/Todomvc/main.html).
24 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "purescript-angular",
3 | "homepage": "https://github.com/purescript-contrib/purescript-angular",
4 | "description": "AngularJS",
5 | "keywords": [
6 | "purescript"
7 | ],
8 | "license": "MIT",
9 | "ignore": [
10 | "**/.*",
11 | "node_modules",
12 | "bower_components",
13 | "examples",
14 | "externs",
15 | "js",
16 | "dist"
17 | ],
18 | "dependencies": {
19 | "purescript-arrays": "~0.3.0",
20 | "purescript-either": "~0.1.4",
21 | "purescript-exceptions": "~0.2.2",
22 | "purescript-foldable-traversable": "~0.2.1",
23 | "purescript-maybe": "~0.2.1",
24 | "purescript-transformers": "~0.4.0",
25 | "purescript-tuples": "~0.2.2",
26 | "purescript-simple-dom": "aktowns/purescript-simple-dom#2b6f81d9fe9e161b8ffc3a3885483c8859a475a8"
27 | },
28 | "devDependencies": {
29 | "angular": "1.2.26",
30 | "todomvc-common": "0.1.9",
31 | "purescript-strings": "~0.4.1",
32 | "purescript-control": "~0.2.1",
33 | "purescript-free": "~0.2.0",
34 | "purescript-foreign": "~0.3.0"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/examples/Backend/Main.purs:
--------------------------------------------------------------------------------
1 | module Backend.Main where
2 |
3 | import Control.Monad.Eff
4 | import Data.Either (either)
5 |
6 | import Angular.Http (Http(), get)
7 | import Angular.Module (controller, ngmodule')
8 | import Angular.Promise (liftPromiseEC, runPromiseEC)
9 | import Angular.This (extendThis)
10 |
11 | mainctrl http this = extendThis { text: ""
12 | , submit: submit } this
13 | where
14 | url = "http://localhost:9501/examples/Backend/main.html"
15 | submit a = runPromiseEC (liftPromiseEC $ get url http)
16 | (either (\e -> extendThis { value: "Failed to get" ++ url } this)
17 | (\a -> extendThis { value: a."data" } this))
18 |
19 | main = do
20 | m <- ngmodule' "backend" []
21 | controller "Main" mainctrl' m
22 |
23 | foreign import mainctrl'
24 | """
25 | /*@ngInject*/function mainctrl$prime($http) {
26 | var impl = mainctrl($http)(this);
27 | return impl.apply(this, []);
28 | }
29 | """ :: forall e a. Http -> Eff e Unit
30 |
--------------------------------------------------------------------------------
/examples/Backend/main.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
9 | Backend
10 |
12 |
14 |
16 |
17 |
18 |
24 |
25 | {{mainctrl.value.value0}}
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examples/Todomvc/Controller.purs:
--------------------------------------------------------------------------------
1 | module Todomvc.Controller (todoctrl) where
2 |
3 | import qualified Data.Array as A
4 | import qualified Data.String as S
5 | import Data.Foldable
6 | import Data.Maybe
7 | import Control.Apply ((*>))
8 | import Control.Monad (unless, when)
9 | import Control.Monad.Eff
10 |
11 | import Angular (copy, extend)
12 | import Angular.Location (Location(), getPath, setPath)
13 | import Angular.Scope (Scope(), watch, readScope, extendScope, modifyScope)
14 | import Angular.This (readThis, writeThis)
15 |
16 | import Todomvc.Storage (Store(), Todo(), get, put)
17 |
18 | addTodo scope = do
19 | s <- readScope scope
20 | let title = S.trim s.newTodo
21 | let empty = (S.length title) == 0
22 | unless empty $ do
23 | let todo = { title: title, completed: false }
24 | todos <- get
25 | let res = todos <> [todo]
26 | put res
27 | extendScope { todos: res
28 | , newTodo: ""
29 | , remainingCount: s.remainingCount + 1 } scope
30 |
31 | todoCompleted scope todo
32 | = modifyScope (\s -> do
33 | let change = if todo.completed then -1 else 1
34 | put s.todos
35 | return { remainingCount: s.remainingCount + change }
36 | ) scope
37 |
38 | clearCompletedTodos scope = do
39 | s <- readScope scope
40 | let res = A.filter (\a -> not a.completed) s.todos
41 | put res
42 | extendScope { todos: res } scope
43 |
44 | markAll scope compl
45 | = modifyScope (\s -> do
46 | let res = (\a -> a { completed = not compl }) <$> s.todos
47 | put res
48 | return { todos: res
49 | , remainingCount: if compl then A.length res else 0 }
50 | ) scope
51 |
52 | editTodo scope todo = do
53 | cp <- copy todo
54 | extendScope { editedTodo: Just todo
55 | , originalTodo: Just $ cp } scope
56 |
57 | doneEditing scope todo
58 | = modifyScope (\s -> do
59 | let title = S.trim todo.title
60 | when (S.length title == 0) $ removeTodo scope todo
61 | extend todo { title: title }
62 | put s.todos
63 | return { editedTodo: Nothing }
64 | ) scope
65 |
66 | removeTodo scope todo = do
67 | s <- readScope scope
68 | let res = A.filter (\a -> not $ refEq a todo) s.todos
69 | unless (A.length res == A.length s.todos) do
70 | let c = if todo.completed then 0 else -1
71 | extendScope { todos: res
72 | , remainingCount: s.remainingCount + c } scope
73 | put res
74 |
75 | revertEditing scope todo = do
76 | s <- readScope scope
77 | let res = A.filter (\a -> not $ refEq a todo) s.todos
78 | unless (A.length res == A.length s.todos) do
79 | case s.originalTodo of
80 | Just t -> extendScope { todos: res <> [t] } scope *>
81 | doneEditing scope t
82 | Nothing -> return unit
83 |
84 | watchRemainingCount scope =
85 | let expr = "remainingCount == 0"
86 | listener = \a _ _ -> extendScope { allChecked: a } scope
87 | in watch expr (return listener) false scope
88 |
89 | watchLocationPath scope =
90 | let expr = "location.path()"
91 | listener = \a _ _ -> case a of
92 | "/completed" -> extendScope { statusFilter: { completed: true } } scope
93 | "/active" -> extendScope { statusFilter: { completed: false } } scope
94 | _ -> extendScope { statusFilter: { } } scope
95 | in watch expr (return listener) false scope
96 |
97 | todoctrl scope this location = do
98 | t <- readThis this
99 | path <- getPath location
100 | if S.length path == 0 then setPath "/" location else return ""
101 | watchRemainingCount scope
102 | watchLocationPath scope
103 | todos <- get
104 | let remainingCount = foldl (\b a -> if a.completed then b else b + 1) 0 todos
105 | extendScope { fromMaybe: fromMaybe
106 | , newTodo: ""
107 | , editedTodo: Nothing
108 | , originalTodo: Nothing
109 | , todos: todos
110 | , remainingCount: remainingCount
111 | , location: location
112 | , addTodo: addTodo scope
113 | , todoCompleted: todoCompleted scope
114 | , clearCompletedTodos: clearCompletedTodos scope
115 | , markAll: markAll scope
116 | , editTodo: editTodo scope
117 | , doneEditing: doneEditing scope
118 | , removeTodo: removeTodo scope
119 | , revertEditing: revertEditing scope } scope
120 |
--------------------------------------------------------------------------------
/examples/Todomvc/Escape.purs:
--------------------------------------------------------------------------------
1 | module Todomvc.Escape (EscapeDirective(), escape) where
2 |
3 | import Data.Maybe
4 | import Control.Bind ((>=>))
5 |
6 | import Data.DOM.Simple.Events (keyCode)
7 |
8 | import Angular.Attributes (get)
9 | import Angular.Element (on)
10 | import Angular.Scope (apply, stringApplyExpr)
11 |
12 | foreign import data EscapeDirective :: *
13 |
14 | escapeKey = 27
15 |
16 | link scope element attrs = do
17 | on "keydown" (keyCode >=> \kc ->
18 | if kc == escapeKey
19 | then (get attrs) >>= (\as -> apply (stringApplyExpr as.todoEscape) scope)
20 | else return unit) element
21 |
22 | foreign import escape
23 | " /*@ngInject*/function escape(){ \
24 | \ return { \
25 | \ link: function($scope, $element, $attrs){ \
26 | \ return link($scope)($element)($attrs)(); \
27 | \ } \
28 | \ }; \
29 | \ } " :: EscapeDirective
30 |
--------------------------------------------------------------------------------
/examples/Todomvc/Focus.purs:
--------------------------------------------------------------------------------
1 | module Todomvc.Focus (FocusDirective(), focus) where
2 |
3 | import Data.Maybe
4 | import Control.Monad (when)
5 | import Control.Monad.Eff
6 |
7 | import qualified Data.DOM.Simple.Element as D
8 |
9 | import Angular.Attributes (get)
10 | import Angular.Element ((!!))
11 | import Angular.Scope (watch, apply, applyExpr)
12 | import Angular.Timeout (timeout)
13 |
14 | foreign import data FocusDirective :: *
15 |
16 | link scope element attrs ngtimeout = do
17 | as <- get attrs
18 | let k = maybe (return unit) D.focus (element !! 0)
19 | watch as.todoFocus (Just (\a _ _ -> when a $ const unit <$> (timeout k 0 false ngtimeout))) false scope
20 |
21 | foreign import focus
22 | " /*@ngInject*/function focus($timeout){ \
23 | \ return { \
24 | \ link: function($scope, $element, $attrs){ \
25 | \ return link($scope)($element)($attrs)($timeout)(); \
26 | \ } \
27 | \ }; \
28 | \ } " :: FocusDirective
29 |
--------------------------------------------------------------------------------
/examples/Todomvc/Main.purs:
--------------------------------------------------------------------------------
1 | module Todomvc.Main where
2 |
3 | import Angular.Module (controller, directive, ngmodule')
4 | import Angular.DI (annotate)
5 |
6 | import Todomvc.Controller (todoctrl)
7 | import Todomvc.Escape (escape)
8 | import Todomvc.Focus (focus)
9 |
10 | main = do
11 | m <- ngmodule' "todomvc" []
12 | controller "TodoCtrl" (annotate todoctrl) m
13 | directive "todoEscape" escape m
14 | directive "todoFocus" focus m
15 |
--------------------------------------------------------------------------------
/examples/Todomvc/Storage.purs:
--------------------------------------------------------------------------------
1 | module Todomvc.Storage
2 | ( Todo(..)
3 | , Store(..)
4 | , get
5 | , put
6 | ) where
7 |
8 | import Control.Monad.Eff
9 |
10 | type Todo = { title :: String , completed :: Boolean }
11 |
12 | foreign import data Store :: !
13 |
14 | storageId :: String
15 | storageId = "todos-angularjs-perf-purs"
16 |
17 | foreign import get
18 | " function get(){ \
19 | \ return JSON.parse(localStorage.getItem(storageId) || '[]'); \
20 | \ }"
21 | :: forall e. Eff (store :: Store | e) [Todo]
22 |
23 | foreign import put
24 | " function put(todos){ \
25 | \ return function(){ \
26 | \ return localStorage.setItem(storageId, JSON.stringify(todos)); \
27 | \ }; \
28 | \ }"
29 | :: forall e. [Todo] -> Eff (store :: Store | e) Unit
30 |
--------------------------------------------------------------------------------
/examples/Todomvc/main.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | AngularJS • TodoMVC
8 |
10 |
12 |
13 |
14 |
16 |
17 |
todos
18 |
25 |
26 |
29 |
33 |
34 |
35 |
37 |
38 |
42 |
43 |
45 |
46 |
54 |
55 |
56 |
57 |
82 |
83 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/examples/TodomvcF/AppI.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.AppI
2 | ( AppE()
3 | , run
4 | ) where
5 |
6 | import Control.Alt ((<|>))
7 | import Control.Monad.Eff (Eff())
8 | import Control.Monad.Free (goEffC, goMC)
9 | import Data.Coyoneda (Natural())
10 | import Data.Inject (prj)
11 | import Data.Maybe.Unsafe (fromJust)
12 |
13 | import TodomvcF.StorageI (Store(), storageN)
14 | import TodomvcF.ThisF (ThisF(), ForeignThis())
15 | import TodomvcF.ThisI (FThis(), thisN)
16 | import TodomvcF.TodomvcF (Todomvc())
17 | import TodomvcF.TodomvcI (AppF(), AppT(), App(), todomvcN)
18 |
19 | type AppE e = Eff (store :: Store, this :: FThis | e)
20 |
21 | appN :: forall e. Natural AppF (AppE e)
22 | appN fa = fromJust $ (storageN <$> prj fa) <|>
23 | ((thisN :: forall e. Natural (ThisF AppT)
24 | (Eff (this :: FThis | e))) <$> prj fa)
25 |
26 | runTodomvc :: forall a. ForeignThis AppT -> Todomvc a -> App a
27 | runTodomvc t = goMC (todomvcN t)
28 |
29 | runApp :: forall e a. App a -> AppE e a
30 | runApp = goEffC appN
31 |
32 | run :: forall e a. ForeignThis AppT -> Todomvc a -> AppE e a
33 | run t = runApp <<< (runTodomvc t)
34 |
--------------------------------------------------------------------------------
/examples/TodomvcF/Escape.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.Escape (EscapeDirective(), escape) where
2 |
3 | import Data.Maybe
4 | import Control.Bind ((>=>))
5 |
6 | import Data.DOM.Simple.Events (keyCode)
7 |
8 | import Angular.Attributes (get)
9 | import Angular.Element (on)
10 | import Angular.Scope (apply, stringApplyExpr)
11 |
12 | foreign import data EscapeDirective :: *
13 |
14 | escapeKey = 27
15 |
16 | link scope element attrs = on "keydown" (keyCode >=> \kc ->
17 | if kc == escapeKey
18 | then (get attrs) >>= (\as -> apply (stringApplyExpr as.todoEscape) scope)
19 | else return unit) element
20 |
21 | foreign import escape """
22 | /*@ngInject*/function escape(){
23 | return {
24 | link: function($scope, $element, $attrs){
25 | return link($scope)($element)($attrs)();
26 | }
27 | };
28 | }
29 | """ :: EscapeDirective
30 |
--------------------------------------------------------------------------------
/examples/TodomvcF/Focus.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.Focus (FocusDirective(), focus) where
2 |
3 | import Data.Maybe
4 | import Control.Monad (when)
5 | import Control.Monad.Eff
6 |
7 | import qualified Data.DOM.Simple.Element as D
8 |
9 | import Angular.Attributes (get)
10 | import Angular.Element ((!!))
11 | import Angular.Scope (watch, apply, applyExpr)
12 | import Angular.Timeout (timeout)
13 |
14 | foreign import data FocusDirective :: *
15 |
16 | link scope element attrs ngtimeout = do
17 | as <- get attrs
18 | let k = maybe (return unit) D.focus (element !! 0)
19 | watch as.todoFocus (Just (\a _ _ -> when a $ const unit <$> (timeout k 0 false ngtimeout))) false scope
20 |
21 | foreign import focus """
22 | /*@ngInject*/function focus($timeout){
23 | return {
24 | link: function($scope, $element, $attrs){
25 | return link($scope)($element)($attrs)($timeout)();
26 | }
27 | };
28 | }
29 | """ :: FocusDirective
30 |
--------------------------------------------------------------------------------
/examples/TodomvcF/Main.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.Main where
2 |
3 | import Control.Monad.Eff (Eff())
4 | import Data.Array (filter, length)
5 | import Data.Maybe (Maybe(..), fromMaybe)
6 | import qualified Data.String as S
7 |
8 | import Angular.Module (controller, directive, ngmodule')
9 | import Angular.Location (getPath, setPath)
10 | import Angular.This (readThis, extendThis)
11 |
12 | import TodomvcF.AppI (run)
13 | import TodomvcF.Escape (escape)
14 | import TodomvcF.Focus (focus)
15 | import TodomvcF.ThisF (ForeignThis())
16 | import TodomvcF.TodomvcF (Todo(..), add, all, remove, edit, revert, clearCompleted, markAll, completed, doneEdit)
17 | import TodomvcF.TodomvcI (AppT(..))
18 |
19 | mainctrl this location =
20 | let app = { newTodo: ""
21 | , todos: []
22 | , remainingCount: 0
23 | , originalTodo: Nothing :: Maybe Todo
24 | , editedTodo: Nothing :: Maybe Todo }
25 | in do
26 | getPath location >>= (\p -> if S.length p == 0 then setPath "/" location else pure "")
27 | todos <- run (toForeignThis $ AppT app) all
28 | let app' = app { todos = todos
29 | , remainingCount = length (filter (\(Todo t) -> not t.completed) todos) }
30 | extendThis { add: add
31 | , all: all
32 | , remove: remove
33 | , edit: edit
34 | , revert: revert
35 | , clearCompleted: clearCompleted
36 | , markAll: markAll
37 | , completed: completed
38 | , doneEdit: doneEdit
39 | , statusFilter: statusFilter
40 | , location: location
41 | , fromMaybe: fromMaybe
42 | , run: (run <<< toForeignThis <<< AppT) app'
43 | , app: app' } this
44 | where
45 | statusFilter = (\path -> case path of
46 | "/completed" -> Just { completed: true }
47 | "/active" -> Just { completed: false }
48 | _ -> Nothing) <$> getPath location
49 |
50 | main = do
51 | m <- ngmodule' "todomvcf" []
52 | controller "Main" mainctrl' m
53 | directive "todoEscape" escape m
54 | directive "todoFocus" focus m
55 |
56 | foreign import toForeignThis """
57 | function toForeignThis(that){
58 | return that;
59 | }
60 | """ :: AppT -> ForeignThis AppT
61 |
62 | foreign import mainctrl' """
63 | /*@ngInject*/function mainctrl$prime($location) {
64 | var impl = mainctrl(this)($location);
65 | return impl.apply(this, []);
66 | }
67 | """ :: forall e a. Eff e Unit
68 |
--------------------------------------------------------------------------------
/examples/TodomvcF/StorageF.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.StorageF
2 | ( Storage()
3 | , StorageF(..)
4 | , Key()
5 | , Value()
6 | , get
7 | , set
8 | ) where
9 |
10 | import Control.Monad.Free (FreeC(), liftFC)
11 | import Data.Foreign (Foreign())
12 | import Data.Maybe (Maybe())
13 |
14 | type Storage a = FreeC StorageF a
15 |
16 | type Key = String
17 |
18 | type Value = Foreign
19 |
20 | data StorageF a
21 | = Get Key (Maybe Value -> a)
22 | | Set Key Value a
23 |
24 | get :: Key -> Storage (Maybe Value)
25 | get k = liftFC $ Get k id
26 |
27 | set :: Key -> Value -> Storage Unit
28 | set k v = liftFC $ Set k v unit
29 |
--------------------------------------------------------------------------------
/examples/TodomvcF/StorageI.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.StorageI
2 | ( Store()
3 | , storageN
4 | ) where
5 |
6 | import Control.Monad.Eff (Eff())
7 | import Data.Coyoneda (Natural())
8 | import Data.Function (Fn3(..), runFn3)
9 | import Data.Maybe (Maybe(..))
10 |
11 | import TodomvcF.StorageF (StorageF(..), Key(), Value())
12 |
13 | foreign import data Store :: !
14 |
15 | storageN :: forall e. Natural StorageF (Eff (store :: Store | e))
16 | storageN (Get k l) = l <$> runFn3 getFn Nothing Just k
17 | storageN (Set k v a) = const a <$> runFn3 setFn unit k v
18 |
19 | foreign import getFn """
20 | function getFn(nothing, just, key) {
21 | return function(){
22 | var value = localStorage.getItem(key);
23 | return value ? just(value) : nothing;
24 | };
25 | }
26 | """ :: forall e. Fn3 (Maybe Value)
27 | (Value -> Maybe Value)
28 | Key
29 | (Eff (store :: Store | e) (Maybe Value))
30 |
31 | foreign import setFn """
32 | function setFn(unit, key, value){
33 | return function(){
34 | localStorage.setItem(key, JSON.stringify(value));
35 | return unit;
36 | };
37 | }
38 | """ :: forall e. Fn3 Unit
39 | Key
40 | Value
41 | (Eff (store :: Store | e) Unit)
42 |
--------------------------------------------------------------------------------
/examples/TodomvcF/ThisF.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.ThisF
2 | ( This()
3 | , ThisF(..)
4 | , ForeignThis()
5 | , read
6 | , extend
7 | ) where
8 |
9 | import Control.Monad.Free (FreeC(), liftFC)
10 |
11 | foreign import data ForeignThis :: * -> *
12 |
13 | type This b a = FreeC (ThisF b) a
14 |
15 | data ThisF b a
16 | = Read (ForeignThis b) (b -> a)
17 | | Extend b (ForeignThis b) a
18 |
19 | read :: forall b. ForeignThis b -> This b b
20 | read t = liftFC $ Read t id
21 |
22 | extend :: forall b. b -> ForeignThis b -> This b Unit
23 | extend b t = liftFC $ Extend b t unit
24 |
--------------------------------------------------------------------------------
/examples/TodomvcF/ThisI.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.ThisI
2 | ( FThis()
3 | , thisN
4 | ) where
5 |
6 | import Control.Monad.Eff (Eff())
7 | import Data.Coyoneda (Natural())
8 | import Data.Function (Fn3(..), runFn3)
9 |
10 | import TodomvcF.ThisF (ThisF(..), ForeignThis())
11 |
12 | foreign import data FThis :: !
13 |
14 | thisN :: forall b e. Natural (ThisF b) (Eff (this :: FThis | e))
15 | thisN (Read t k) = (pure <<< k <<< readFn) t
16 | thisN (Extend b t a) = const a <$> runFn3 extendFn unit b t
17 |
18 | foreign import readFn """
19 | function readFn(that) {
20 | return that;
21 | }
22 | """ :: forall b. ForeignThis b -> b
23 |
24 | foreign import extendFn """
25 | function extendFn(unit, b, that){
26 | return function(){
27 | angular.extend(that, b);
28 | return unit;
29 | };
30 | }
31 | """ :: forall b e. Fn3 Unit
32 | b
33 | (ForeignThis b)
34 | (Eff (this :: FThis | e) Unit)
35 |
--------------------------------------------------------------------------------
/examples/TodomvcF/TodomvcF.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.TodomvcF
2 | ( Todo(..)
3 | , Todomvc()
4 | , TodomvcF(..)
5 | , add
6 | , remove
7 | , edit
8 | , revert
9 | , all
10 | , clearCompleted
11 | , markAll
12 | , completed
13 | , doneEdit
14 | ) where
15 |
16 | import Control.Monad.Free (FreeC(), liftFC)
17 | import Data.Foreign.Class (IsForeign, read, readProp)
18 |
19 | newtype Todo = Todo { title :: String , completed :: Boolean }
20 |
21 | type Todomvc a = FreeC TodomvcF a
22 |
23 | data TodomvcF a
24 | = Add Todo a
25 | | Remove Todo a
26 | | Edit Todo a
27 | | Revert Todo a
28 | | All ([Todo] -> a)
29 | | ClearCompleted a
30 | | MarkAll Boolean a
31 | | Completed Todo a
32 | | DoneEdit Todo a
33 |
34 | instance todoIsForeign :: IsForeign Todo where
35 | read a = do
36 | title <- readProp "title" a
37 | completed <- readProp "completed" a
38 | return $ Todo { title: title
39 | , completed: completed }
40 |
41 | add :: Todo -> Todomvc Unit
42 | add t = liftFC $ Add t unit
43 |
44 | remove :: Todo -> Todomvc Unit
45 | remove t = liftFC $ Remove t unit
46 |
47 | edit :: Todo -> Todomvc Unit
48 | edit t = liftFC $ Edit t unit
49 |
50 | doneEdit :: Todo -> Todomvc Unit
51 | doneEdit t = liftFC $ DoneEdit t unit
52 |
53 | revert :: Todo -> Todomvc Unit
54 | revert t = liftFC $ Revert t unit
55 |
56 | all :: Todomvc [Todo]
57 | all = liftFC $ All id
58 |
59 | clearCompleted :: Todomvc Unit
60 | clearCompleted = liftFC $ ClearCompleted unit
61 |
62 | markAll :: Boolean -> Todomvc Unit
63 | markAll c = liftFC $ MarkAll c unit
64 |
65 | completed :: Todo -> Todomvc Unit
66 | completed t = liftFC $ Completed t unit
67 |
--------------------------------------------------------------------------------
/examples/TodomvcF/TodomvcI.purs:
--------------------------------------------------------------------------------
1 | module TodomvcF.TodomvcI
2 | ( AppF()
3 | , App()
4 | , AppT(..)
5 | , todomvcN
6 | ) where
7 |
8 | import Control.Alt ((<|>))
9 | import Control.Monad (unless, when)
10 | import Control.Monad.Eff (Eff())
11 | import Control.Monad.Free (FreeC(), injC)
12 | import Data.Coyoneda (Natural())
13 | import Data.Either (either)
14 | import Data.Foreign (F(), toForeign, readString)
15 | import Data.Foreign.Class (readJSON)
16 | import Data.Functor.Coproduct (Coproduct())
17 | import Data.Maybe (Maybe(..), maybe)
18 | import qualified Data.Array as A
19 | import qualified Data.String as S
20 |
21 | import TodomvcF.TodomvcF (TodomvcF(..), Todo(..))
22 | import TodomvcF.StorageF (StorageF(), get, set)
23 | import TodomvcF.ThisF (ThisF(), ForeignThis(), read, extend)
24 |
25 | newtype AppT = AppT { remainingCount :: Number
26 | , todos :: [Todo]
27 | , newTodo :: String
28 | , originalTodo :: Maybe Todo
29 | , editedTodo :: Maybe Todo }
30 |
31 | type AppF = Coproduct StorageF (ThisF AppT)
32 |
33 | type App = FreeC AppF
34 |
35 | todomvcN :: ForeignThis AppT -> Natural TodomvcF App
36 | todomvcN this fa =
37 | case fa of
38 | Add (Todo t) a -> let title = S.trim t.title
39 | empty = (S.length title == 0)
40 | in const a <$> unless empty do
41 | todos <- getOrEmpty
42 | let todos' = [Todo t { title = title }] <> todos
43 | setTodos todos'
44 | AppT this' <- injC $ read this
45 | extendApp (this' { remainingCount = this'.remainingCount + 1
46 | , todos = todos'
47 | , newTodo = "" }) this
48 |
49 | Remove (Todo t) a -> const a <$> remove t
50 |
51 | Edit (Todo t) a -> do
52 | AppT this' <- injC $ read this
53 | extendApp (this' { originalTodo = (Just <<< Todo) t { title = t.title }
54 | , editedTodo = (Just <<< Todo) t }) this
55 | return a
56 |
57 | DoneEdit (Todo t) a -> let title = S.trim t.title
58 | empty = (S.length title == 0)
59 | in do
60 | AppT this' <- injC $ read this
61 | if empty then remove t else setTodos this'.todos
62 | extendApp (this' { editedTodo = Nothing }) this
63 | return a
64 |
65 | Revert (Todo t) a -> do
66 | AppT this' <- injC $ read this
67 | let res = A.filter (not <<< refEq t <<< todoi) this'.todos
68 | n = A.length res
69 | m = A.length this'.todos
70 | const a <$>
71 | unless (n == m) (maybe (return unit)
72 | (\t -> let todos = [t] <> res
73 | in do
74 | setTodos todos
75 | extendApp (this' { todos = todos }) this
76 | return unit) this'.originalTodo)
77 |
78 | All k -> k <$> getOrEmpty
79 |
80 | ClearCompleted a -> do
81 | AppT this' <- injC $ read this
82 | let completed = A.filter (not <<< completedi) this'.todos
83 | setTodos completed
84 | extendApp (this' { remainingCount = this'.remainingCount
85 | , todos = completed }) this
86 | return a
87 |
88 | MarkAll v a -> do
89 | AppT this' <- injC $ read this
90 | let marked = (\(Todo a) -> Todo $ a { completed = not v }) <$> this'.todos
91 | setTodos marked
92 | extendApp (this' { remainingCount = if v then A.length marked else 0
93 | , todos = marked }) this
94 | return a
95 |
96 | Completed (Todo t) a -> do
97 | AppT this' <- injC $ read this
98 | setTodos this'.todos
99 | extendApp (this' { remainingCount = this'.remainingCount +
100 | if t.completed then -1 else 1 }) this
101 | return a
102 |
103 | where
104 | key = "todos-angularjs-perf-purs-f"
105 | completedi (Todo a) = a.completed
106 | todoi (Todo a) = a
107 | parse r = either (const []) id (readString r >>= readJSON)
108 | getOrEmpty = injC $ maybe [] parse <$> get key
109 | setTodos as = injC $ set key (toForeign as)
110 | extendApp a t = injC $ extend (AppT a) t
111 | remove t = do
112 | AppT this' <- injC $ read this
113 | let res = A.filter (not <<< refEq t <<< todoi) this'.todos
114 | n = A.length res
115 | m = A.length this'.todos
116 | unless (n == m) do
117 | setTodos res
118 | extendApp (this' { remainingCount = this'.remainingCount + if t.completed then 0 else -1
119 | , todos = res }) this
120 |
--------------------------------------------------------------------------------
/examples/TodomvcF/main.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | AngularJS • TodoMVC
8 |
10 |
12 |
13 |
14 |
16 |
17 |
todos
18 |
26 |
27 |
30 |
34 |
35 |
36 |
40 |
41 |
45 |
46 |
48 |
49 |
57 |
58 |
59 |
60 |
88 |
89 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | , clean = require('gulp-clean')
3 | , gutil = require('gulp-util')
4 | , plumber = require('gulp-plumber')
5 | , purescript = require('gulp-purescript')
6 | , http = require('http')
7 | , nstatic = require('node-static')
8 | , config = {
9 | clean: ['dist', '.psci_modules'],
10 | purescript: {
11 | src: [
12 | 'bower_components/purescript-*/src/**/*.purs*',
13 | 'src/**/*.purs'
14 | ],
15 | examples: {
16 | todomvc: {
17 | src: 'examples/Todomvc/**/*.purs',
18 | options: {
19 | main: 'Todomvc.Main',
20 | output: 'todomvc.js'
21 | }
22 | },
23 | todomvcf: {
24 | src: 'examples/TodomvcF/**/*.purs',
25 | options: {
26 | main: 'TodomvcF.Main',
27 | output: 'todomvcf.js'
28 | }
29 | },
30 | backend: {
31 | src: 'examples/Backend/**/*.purs',
32 | options: {
33 | main: 'Backend.Main',
34 | output: 'backend.js'
35 | }
36 | }
37 | },
38 | dest: 'dist',
39 | docs: 'MODULE.md'
40 | },
41 | nstatic: {
42 | root: '.',
43 | port: 9501
44 | }
45 | }
46 | ;
47 |
48 | function error(e) {
49 | gutil.log(gutil.colors.magenta('>>>> Error <<<<') + '\n' + e.toString().trim());
50 | this.emit('end');
51 | }
52 |
53 | function server(cb) {
54 | var file = new nstatic.Server(config.nstatic.root);
55 | http.createServer(function(request, response){
56 | request.addListener('end', function(){
57 | file.serve(request, response);
58 | }).resume();
59 | }).listen(config.nstatic.port, function(){
60 | gutil.log('Listening on port ' + gutil.colors.magenta(config.nstatic.port));
61 | cb();
62 | });
63 | }
64 |
65 | function example(ex) {
66 | return (gulp.src([ex.src].concat(config.purescript.src)).
67 | pipe(plumber()).
68 | pipe(purescript.psc(ex.options)).
69 | on('error', error).
70 | pipe(gulp.dest(config.purescript.dest)));
71 | }
72 |
73 | gulp.task('clean', function(){
74 | return (
75 | gulp.src(config.clean, {read: false}).
76 | pipe(clean())
77 | );
78 | });
79 |
80 | gulp.task('todomvc', ['clean'], function(){
81 | return example(config.purescript.examples.todomvc);
82 | });
83 |
84 | gulp.task('todomvcf', ['clean'], function(){
85 | return example(config.purescript.examples.todomvcf);
86 | });
87 |
88 | gulp.task('backend', ['clean'], function(){
89 | return example(config.purescript.examples.backend);
90 | });
91 |
92 | gulp.task('make', function(){
93 | return (
94 | gulp.src(config.purescript.src).
95 | pipe(plumber()).
96 | pipe(purescript.pscMake({output: config.purescript.dest})).
97 | on('error', error)
98 | );
99 | });
100 |
101 | gulp.task('psci', function(){
102 | return (
103 | gulp.src(config.purescript.src).
104 | pipe(plumber()).
105 | pipe(purescript.dotPsci()).
106 | on('error', error)
107 | );
108 | });
109 |
110 | gulp.task('docs', function(){
111 | return (
112 | gulp.src(config.purescript.src[1]).
113 | pipe(plumber()).
114 | pipe(purescript.pscDocs()).
115 | on('error', error).
116 | pipe(gulp.dest(config.purescript.docs))
117 | );
118 | });
119 |
120 | gulp.task('watch', function(cb){
121 | gulp.watch(config.purescript.src, ['make']);
122 | });
123 |
124 | gulp.task('watch.todomvc', function(cb){
125 | gulp.watch([config.purescript.examples.todomvc.src].concat(config.purescript.src), ['todomvc']);
126 | server(cb);
127 | });
128 |
129 | gulp.task('watch.todomvcf', function(cb){
130 | gulp.watch([config.purescript.examples.todomvcf.src].concat(config.purescript.src), ['todomvcf']);
131 | server(cb);
132 | });
133 |
134 | gulp.task('watch.backend', function(cb){
135 | gulp.watch([config.purescript.examples.backend.src].concat(config.purescript.src), ['backend']);
136 | server(cb);
137 | });
138 |
139 | gulp.task('default', ['clean', 'make', 'docs', 'psci']);
140 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "purescript-angular",
3 | "private": true,
4 | "devDependencies": {
5 | "gulp": "3.8.10",
6 | "gulp-clean": "0.3.1",
7 | "gulp-plumber": "0.6.4",
8 | "gulp-purescript": "0.1.2",
9 | "gulp-util": "3.0.0",
10 | "node-static": "0.7.4"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Angular.purs:
--------------------------------------------------------------------------------
1 | module Angular where
2 |
3 | import Control.Monad.Eff
4 |
5 | import Angular.Injector (Injector())
6 | import Angular.Element (Element())
7 |
8 | -- | bind
9 |
10 | foreign import bootstrap
11 | " function bootstrap(element) { \
12 | \ return function(modules){ \
13 | \ return function(){ \
14 | \ return angular.bootstrap(element, modules); \
15 | \ }; \
16 | \ }; \
17 | \ }"
18 | :: forall e. Element -> [String] -> Eff e Injector
19 |
20 | foreign import copy
21 | " function copy(src) { \
22 | \ return function() { \
23 | \ return angular.copy(src); \
24 | \ }; \
25 | \ }" :: forall e a. a -> Eff e a
26 |
27 | -- | element => Angular.Element
28 |
29 | -- | equals
30 |
31 | foreign import extend
32 | " function extend(dst) { \
33 | \ return function(src) { \
34 | \ return function() { \
35 | \ return angular.extend(dst, src); \
36 | \ }; \
37 | \ }; \
38 | \ }" :: forall e a b c. { | a } -> { | b } -> Eff e { | c }
39 |
40 | -- | forEach
41 |
42 | -- | fromJson
43 |
44 | -- | identity
45 |
46 | -- | injector, see Angular.Injector
47 |
48 | foreign import isArray
49 | " function isArray(value) { \
50 | \ return function() { \
51 | \ return angular.isArray(value); \
52 | \ }; \
53 | \ }" :: forall e a. a -> Eff e Boolean
54 |
55 | foreign import isDate
56 | " function isDate(value) { \
57 | \ return function() { \
58 | \ return angular.isDate(value); \
59 | \ }; \
60 | \ }" :: forall e a. a -> Eff e Boolean
61 |
62 | foreign import isDefined
63 | " function isDefined(value) { \
64 | \ return function() { \
65 | \ return angular.isDefined(value); \
66 | \ }; \
67 | \ }" :: forall e a. a -> Eff e Boolean
68 |
69 | foreign import isElement
70 | " function isElement(value) { \
71 | \ return function() { \
72 | \ return angular.isElement(value); \
73 | \ }; \
74 | \ }" :: forall e a. a -> Eff e Boolean
75 |
76 | foreign import isFunction
77 | " function isFunction(value) { \
78 | \ return function() { \
79 | \ return angular.isFunction(value); \
80 | \ }; \
81 | \ }" :: forall e a. a -> Eff e Boolean
82 |
83 | foreign import isNumber
84 | " function isNumber(value) { \
85 | \ return function() { \
86 | \ return angular.isNumber(value); \
87 | \ }; \
88 | \ }" :: forall e a. a -> Eff e Boolean
89 |
90 | foreign import isObject
91 | " function isObject(value) { \
92 | \ return function() { \
93 | \ return angular.isObject(value); \
94 | \ }; \
95 | \ }" :: forall e a. a -> Eff e Boolean
96 |
97 | foreign import isString
98 | " function isString(value) { \
99 | \ return function() { \
100 | \ return angular.isString(value); \
101 | \ }; \
102 | \ }" :: forall e a. a -> Eff e Boolean
103 |
104 | foreign import isUndefined
105 | " function isUndefined(value) { \
106 | \ return function() { \
107 | \ return angular.isUndefined(value); \
108 | \ }; \
109 | \ }" :: forall e a. a -> Eff e Boolean
110 |
111 | foreign import lowercase
112 | " function lowercase(str) { \
113 | \ return function() { \
114 | \ return angular.lowercase(str); \
115 | \ }; \
116 | \ }" :: forall e. String -> Eff e String
117 |
118 | -- | module => Angular.Module
119 |
120 | -- | noop
121 |
122 | -- | toJson
123 |
124 | -- | uppercase
125 |
--------------------------------------------------------------------------------
/src/Angular/Animate.purs:
--------------------------------------------------------------------------------
1 | module Angular.Animate
2 | ( NgAnimate()
3 | , Animate()
4 | , AnimateEff()
5 | , enter
6 | , leave
7 | , move
8 | , addClass
9 | , removeClass
10 | , setClass
11 | ) where
12 |
13 | import Control.Monad.Eff
14 | import Data.Function
15 | import Data.Maybe
16 |
17 | import Angular.Element (Element())
18 |
19 | foreign import data Animate :: *
20 |
21 | foreign import data NgAnimate :: !
22 |
23 | type AnimateEff e = Eff (nganimate :: NgAnimate | e) Unit
24 |
25 | foreign import enterMoveFn
26 | " function enterMoveFn(fn, fromMaybe, element, parent, after, done, $animate){ \
27 | \ return function(){ \
28 | \ return $animate[fn](element, parent, after, fromMaybe(undefined)(done)); \
29 | \ }; \
30 | \ } "
31 | :: forall e f r. Fn7 String
32 | (Eff f r -> Maybe (Eff f r) -> Eff f r)
33 | Element
34 | Element
35 | Element
36 | (Maybe (Eff f r))
37 | Animate
38 | (AnimateEff e)
39 |
40 | enter :: forall e f r. Element -> Element -> Element -> Maybe (Eff f r) -> Animate -> AnimateEff e
41 | enter = runFn7 enterMoveFn "enter" fromMaybe
42 |
43 | move :: forall e f r. Element -> Element -> Element -> Maybe (Eff f r) -> Animate -> AnimateEff e
44 | move = runFn7 enterMoveFn "move" fromMaybe
45 |
46 | foreign import leaveFn
47 | " function leaveFn(fromMaybe, element, done, $animate){ \
48 | \ return function(){ \
49 | \ return $animate.leave(element, fromMaybe(undefined)(done)); \
50 | \ }; \
51 | \ } "
52 | :: forall e f r. Fn4 (Eff f r -> Maybe (Eff f r) -> Eff f r)
53 | Element
54 | (Maybe (Eff f r))
55 | Animate
56 | (AnimateEff e)
57 |
58 | leave :: forall e f r. Element -> Maybe (Eff f r) -> Animate -> AnimateEff e
59 | leave = runFn4 leaveFn fromMaybe
60 |
61 | foreign import addRemoveClassFn
62 | " function addRemoveClassFn(fn, fromMaybe, element, className, done, $animate){ \
63 | \ return function(){ \
64 | \ return $animate[fn](element, className, fromMaybe(undefined)(done)); \
65 | \ }; \
66 | \ } "
67 | :: forall e f r. Fn6 String
68 | (Eff f r -> Maybe (Eff f r) -> Eff f r)
69 | Element
70 | String
71 | (Maybe (Eff f r))
72 | Animate
73 | (AnimateEff e)
74 |
75 | addClass :: forall e f r. Element -> String -> Maybe (Eff f r) -> Animate -> AnimateEff e
76 | addClass = runFn6 addRemoveClassFn "addClass" fromMaybe
77 |
78 | removeClass :: forall e f r. Element -> String -> Maybe (Eff f r) -> Animate -> AnimateEff e
79 | removeClass = runFn6 addRemoveClassFn "removeClass" fromMaybe
80 |
81 | foreign import setClassFn
82 | " function setClassFn(fromMaybe, element, add, remove, done, $animate){ \
83 | \ return function(){ \
84 | \ return $animate.setClass(element, add, remove, fromMaybe(undefined)(done)); \
85 | \ }; \
86 | \ } "
87 | :: forall e f r. Fn6 (Eff f r -> Maybe (Eff f r) -> Eff f r)
88 | Element
89 | String
90 | String
91 | (Maybe (Eff f r))
92 | Animate
93 | (AnimateEff e)
94 |
95 | setClass :: forall e f r. Element -> String -> String -> Maybe (Eff f r) -> Animate -> AnimateEff e
96 | setClass = runFn6 setClassFn fromMaybe
97 |
--------------------------------------------------------------------------------
/src/Angular/Attributes.purs:
--------------------------------------------------------------------------------
1 | module Angular.Attributes
2 | ( Attributes()
3 | , NgAttr()
4 | , AttrEff()
5 | , addClass
6 | , removeClass
7 | , updateClass
8 | , observe
9 | , set
10 | , get
11 | , attr
12 | ) where
13 |
14 | import Control.Monad.Eff
15 |
16 | foreign import data Attributes :: *
17 |
18 | foreign import data NgAttr :: !
19 |
20 | type AttrEff e r = Eff (ngattr :: NgAttr | e) r
21 |
22 | foreign import addClass
23 | " function addClass(classVal){ \
24 | \ return function(attrs){ \
25 | \ return function(){ \
26 | \ return attrs.$addClass(classVal); \
27 | \ }; \
28 | \ }; \
29 | \ }"
30 | :: forall e. String -> Attributes -> AttrEff e Unit
31 |
32 | foreign import removeClass
33 | " function removeClass(classVal){ \
34 | \ return function(attrs){ \
35 | \ return function(){ \
36 | \ return attrs.$removeClass(classVal); \
37 | \ }; \
38 | \ }; \
39 | \ }"
40 | :: forall e. String -> Attributes -> AttrEff e Unit
41 |
42 | foreign import updateClass
43 | " function updateClass(newClasses){ \
44 | \ return function(oldClasses){ \
45 | \ return function(attrs){ \
46 | \ return function(){ \
47 | \ return attrs.$updateClass(newClasses, oldClasses); \
48 | \ }; \
49 | \ }; \
50 | \ }; \
51 | \ }"
52 | :: forall e. String -> String -> Attributes -> AttrEff e Unit
53 |
54 | foreign import observe
55 | " function observe(key){ \
56 | \ return function(k){ \
57 | \ return function(attrs){ \
58 | \ return function(){ \
59 | \ return attrs.$observe(key, function(v){return k(v)();}); \
60 | \ }; \
61 | \ }; \
62 | \ }; \
63 | \ }"
64 | :: forall e f. String -> (String -> Eff f Unit) -> Attributes -> AttrEff e Unit
65 |
66 | foreign import set
67 | " function set(name){ \
68 | \ return function(value){ \
69 | \ return function(attrs){ \
70 | \ return function(){ \
71 | \ return attrs.$set(name, value); \
72 | \ }; \
73 | \ }; \
74 | \ }; \
75 | \ }"
76 | :: forall e. String -> String -> Attributes -> AttrEff e Unit
77 |
78 | foreign import get
79 | " function get(attrs){ \
80 | \ return function(){ \
81 | \ return attrs; \
82 | \ }; \
83 | \ }"
84 | :: forall e a. Attributes -> AttrEff e { | a }
85 |
86 | foreign import attr
87 | " function attr(attrs){ \
88 | \ return function(){ \
89 | \ return attrs.$attr; \
90 | \ }; \
91 | \ }"
92 | :: forall e a. Attributes -> AttrEff e { | a }
93 |
--------------------------------------------------------------------------------
/src/Angular/Cache.purs:
--------------------------------------------------------------------------------
1 | module Angular.Cache
2 | ( Cache()
3 | , CacheFactory()
4 | , CacheEff()
5 | , NgCache()
6 | , Key()
7 | , Name()
8 | , Options()
9 | , cache
10 | , put
11 | , get
12 | , remove
13 | , removeAll
14 | , destroy
15 | , info
16 | ) where
17 |
18 | import Control.Monad.Eff
19 | import Data.Maybe
20 | import Data.Function
21 |
22 | foreign import data NgCache :: !
23 |
24 | foreign import data Cache :: *
25 |
26 | foreign import data CacheFactory :: *
27 |
28 | type Key = String
29 |
30 | type Name = String
31 |
32 | type Options a = { capacity :: Number | a }
33 |
34 | type CacheEff e r = Eff (ngcache :: NgCache | e) r
35 |
36 | cache :: forall e a. Name -> Maybe (Options a) -> CacheFactory -> CacheEff e Cache
37 | cache = runFn4 cacheFn fromMaybe
38 |
39 | foreign import cacheFn
40 | " function cacheFn(fromMaybe, name, opts, $cacheFactory){ \
41 | \ return function(){ \
42 | \ return $cacheFactory(name, fromMaybe(undefined)(opts)); \
43 | \ }; \
44 | \ } "
45 | :: forall e a. Fn4 (Options a -> Maybe (Options a) -> Options a)
46 | Name
47 | (Maybe (Options a))
48 | CacheFactory
49 | (CacheEff e Cache)
50 |
51 | foreign import put
52 | " function put(key){ \
53 | \ return function(value){ \
54 | \ return function(cache){ \
55 | \ return function(){ \
56 | \ return cache.put(key, value); \
57 | \ }; \
58 | \ }; \
59 | \ }; \
60 | \ } "
61 | :: forall e a. Key -> a -> Cache -> CacheEff e a
62 |
63 | foreign import get
64 | " function get(key){ \
65 | \ return function(cache){ \
66 | \ return function(){ \
67 | \ return cache.get(key); \
68 | \ }; \
69 | \ }; \
70 | \ } "
71 | :: forall e a. Key -> Cache -> CacheEff e a
72 |
73 | foreign import remove
74 | " function remove(key){ \
75 | \ return function(cache){ \
76 | \ return function(){ \
77 | \ return cache.remove(key); \
78 | \ }; \
79 | \ }; \
80 | \ } "
81 | :: forall e. Key -> Cache -> CacheEff e Unit
82 |
83 | foreign import removeAll
84 | " function removeAll(cache){ \
85 | \ return function(){ \
86 | \ return cache.removeAll(); \
87 | \ }; \
88 | \ } "
89 | :: forall e. Cache -> CacheEff e Unit
90 |
91 | foreign import destroy
92 | " function destroy(cache){ \
93 | \ return function(){ \
94 | \ return cache.destroy(); \
95 | \ }; \
96 | \ } "
97 | :: forall e. Cache -> CacheEff e Unit
98 |
99 | foreign import info
100 | " function info(cache){ \
101 | \ return function(){ \
102 | \ return cache.info(); \
103 | \ }; \
104 | \ } "
105 | :: forall e a. Cache -> CacheEff e { id :: String, size :: Number | a }
106 |
--------------------------------------------------------------------------------
/src/Angular/DI.purs:
--------------------------------------------------------------------------------
1 | module Angular.DI (
2 | Dependency, name
3 | , Service
4 | , RootScope(..)
5 | , RootElement(..)
6 | , get
7 | , Injectable, dependencies
8 | , Annotated()
9 | , annotate
10 | ) where
11 |
12 | import Control.Monad.Eff (Eff())
13 | import Data.Function
14 | import Angular.Injector (Injector(), InjEff())
15 | import Angular.Animate (Animate())
16 | import Angular.Cache (CacheFactory())
17 | import Angular.Http (Http())
18 | import Angular.Interpolate (Interpolate())
19 | import Angular.Interval (Interval())
20 | import Angular.Location (Location())
21 | import Angular.Log (Log())
22 | import Angular.Parse (Parse())
23 | import Angular.Q (Q())
24 | import Angular.Timeout (Timeout())
25 | import Angular.Scope (Scope())
26 | import Angular.Element (Element())
27 | import Angular.Attributes (Attributes())
28 | import Angular.This (This())
29 |
30 | -- | A type which can by provided by dependency injection.
31 | class Dependency a where
32 | name :: String
33 |
34 | -- | Services which can be retrieved with get
35 | class (Dependency a) <= Service a
36 |
37 | instance dependencyInjector :: Dependency Injector where
38 | name = "$injector"
39 | instance serviceInjector :: Service Injector
40 |
41 | instance dependencyAnimate :: Dependency Animate where
42 | name = "$animate"
43 | instance serviceAnimate :: Service Animate
44 |
45 | instance dependencyCacheFactory :: Dependency CacheFactory where
46 | name = "$cacheFactory"
47 | instance serviceCacheFactory :: Service CacheFactory
48 |
49 | instance dependencyHttp :: Dependency Http where
50 | name = "$http"
51 | instance serviceHttp :: Service Http
52 |
53 | instance dependencyInterpolate :: Dependency Interpolate where
54 | name = "$interpolate"
55 | instance serviceInterpolate :: Service Interpolate
56 |
57 | instance dependencyInterval :: Dependency Interval where
58 | name = "$interval"
59 | instance serviceInterval :: Service Interval
60 |
61 | instance dependencyLocation :: Dependency Location where
62 | name = "$location"
63 | instance serviceLocation :: Service Location
64 |
65 | instance dependencyLog :: Dependency Log where
66 | name = "$log"
67 | instance serviceLog :: Service Log
68 |
69 | instance dependencyParse :: Dependency Parse where
70 | name = "$parse"
71 | instance serviceParse :: Service Parse
72 |
73 | instance dependencyQ :: Dependency Q where
74 | name = "$q"
75 | instance serviceQ :: Service Q
76 |
77 | instance dependencyTimeout :: Dependency Timeout where
78 | name = "$timeout"
79 | instance serviceTimeout :: Service Timeout
80 |
81 | newtype RootScope a = RootScope (Scope a)
82 |
83 | instance dependencyRootScope :: Dependency (RootScope a) where
84 | name = "$rootScope"
85 | instance serviceRootScope :: Service (RootScope a)
86 |
87 | instance dependencyScope :: Dependency (Scope a) where
88 | name = "$scope"
89 |
90 | newtype RootElement = RootElement Element
91 |
92 | instance dependencyRootElement :: Dependency RootElement where
93 | name = "$rootElement"
94 | instance serviceRootElement :: Service RootElement
95 |
96 | instance dependencyElement :: Dependency Element where
97 | name = "$element"
98 |
99 | instance dependencyAttributes :: Dependency Attributes where
100 | name = "$attrs"
101 |
102 | instance dependencyThis :: Dependency (This a) where
103 | -- it would be nice to make a dummy service to avoid the special handling
104 | -- in annotate, but there is nowhere to do so
105 | name = "$this"
106 |
107 |
108 | foreign import getDependency
109 | "function get(dependency) {\
110 | \ dependency = dependency.name;\
111 | \ return function ($injector) {\
112 | \ return function () {\
113 | \ return $injector.get(dependency);\
114 | \ };\
115 | \ };\
116 | \}" :: forall e a . (Dependency a) => Injector -> InjEff e a
117 |
118 | get :: forall e a . (Service a) => Injector -> InjEff e a
119 | get = getDependency
120 |
121 |
122 | class Injectable a where
123 | dependencies :: a -> [String]
124 |
125 | instance injectableEff :: Injectable (Eff e r) where
126 | dependencies _ = []
127 |
128 | foreign import dependenciesFn
129 | "function dependenciesFn(dependency) {\
130 | \ dependency = [dependency.name];\
131 | \ return function (injectable) {\
132 | \ return function (/*f*/) {\
133 | \ return dependency.concat(injectable.dependencies(/*f(a)*/));\
134 | \ };\
135 | \ };\
136 | \}" :: forall a b . (Dependency a, Injectable b) => (a -> b) -> [String]
137 |
138 | instance injectableFn :: (Dependency a, Injectable b) => Injectable (a -> b) where
139 | dependencies f = dependenciesFn f
140 |
141 |
142 | -- | An Eff function with added dependency injection annotations.
143 | foreign import data Annotated :: * -> *
144 |
145 | -- | Infer and annotate a function with its dependencies, that can provided by Injector.invoke or Module functions.
146 | foreign import annotate
147 | "function annotate(injectable) {\
148 | \ return function (fun) {\
149 | \ var inject = injectable.dependencies(fun);\
150 | \ function g(/*...*/) {\
151 | \ var f = fun;\
152 | \ for (var i = 0, a = 0; i < inject.length; i++)\
153 | \ f = f(inject[i] === '$this' ? this : arguments[a++]);\
154 | \ return f();\
155 | \ }\
156 | \ g.prototype = fun.prototype;\
157 | \ g.$inject = inject.filter(function (d) { return d !== '$this'; });\
158 | \ return g;\
159 | \ };\
160 | \}" :: forall a . (Injectable a) => a -> Annotated a
161 |
--------------------------------------------------------------------------------
/src/Angular/Deferred.purs:
--------------------------------------------------------------------------------
1 | module Angular.Deferred
2 | ( Deferred()
3 | , NgDeferred()
4 | , DeferredEff()
5 | , resolve
6 | , reject
7 | , notify
8 | , promise
9 | ) where
10 |
11 | import Control.Monad.Eff
12 | import Data.Function
13 |
14 | import Angular.Promise (Promise())
15 |
16 | foreign import data Deferred :: * -> * -> *
17 |
18 | foreign import data NgDeferred :: !
19 |
20 | type DeferredEff e r = Eff (ngdeferred :: NgDeferred | e) r
21 |
22 | foreign import resolveFn
23 | " function resolveFn(a, dfd){ \
24 | \ return function(){ \
25 | \ dfd.resolve(a); \
26 | \ }; \
27 | \ } "
28 | :: forall e a b. Fn2 b (Deferred a b) (DeferredEff e Unit)
29 |
30 | resolve :: forall e a b. b -> Deferred a b -> DeferredEff e Unit
31 | resolve = runFn2 resolveFn
32 |
33 | foreign import rejectFn
34 | " function rejectFn(a, dfd){ \
35 | \ return function(){ \
36 | \ dfd.reject(a); \
37 | \ }; \
38 | \ } "
39 | :: forall e a b. Fn2 a (Deferred a b) (DeferredEff e Unit)
40 |
41 | reject :: forall e a b. a -> Deferred a b -> DeferredEff e Unit
42 | reject = runFn2 rejectFn
43 |
44 | foreign import notifyFn
45 | " function notifyFn(a, dfd){ \
46 | \ return function(){ \
47 | \ dfd.notify(a); \
48 | \ }; \
49 | \ } "
50 | :: forall e s a b. Fn2 s (Deferred a b) (DeferredEff e Unit)
51 |
52 | notify :: forall e s a b. s -> Deferred a b -> DeferredEff e Unit
53 | notify = runFn2 notifyFn
54 |
55 | foreign import promise
56 | " function promise(dfd){ \
57 | \ return function(){ \
58 | \ dfd.promise; \
59 | \ }; \
60 | \ } "
61 | :: forall e a b. Deferred a b -> DeferredEff e (Promise a b)
62 |
--------------------------------------------------------------------------------
/src/Angular/Element.purs:
--------------------------------------------------------------------------------
1 | module Angular.Element
2 | ( Element()
3 | , ElEff()
4 | , NgEl()
5 | , Handler()
6 | , DeregisterHandler()
7 | , element
8 | , addClass
9 | , after
10 | , getAttr
11 | , setAttr
12 | , setAllAttr
13 | , bind
14 | , children
15 | , clone
16 | , contents
17 | , getCss
18 | , setCss
19 | , setAllCss
20 | , getData
21 | , setData
22 | , setAllData
23 | , empty
24 | , eq
25 | , find
26 | , hasClass
27 | , html
28 | , next
29 | , on
30 | , off
31 | , offHandler
32 | , one
33 | , parent
34 | , prepend
35 | , getProp
36 | , setProp
37 | , setAllProp
38 | , ready
39 | , remove
40 | , removeAttr
41 | , removeClass
42 | , removeData
43 | , replaceWith
44 | , toggleClass
45 | , triggerHandler
46 | , unbind
47 | , unbindHandler
48 | , getVal
49 | , setVal
50 | , wrap
51 | , controller
52 | , injector
53 | , scope
54 | , isolateScope
55 | , inheritedData
56 | , (!!)
57 | ) where
58 |
59 | import Prelude (Unit())
60 |
61 | import Control.Monad.Eff
62 | import Data.Function (Fn3(), Fn4(), Fn5(), runFn3, runFn4, runFn5)
63 | import Data.Maybe
64 |
65 | import Data.DOM.Simple.Types (HTMLElement(), DOMEvent())
66 |
67 | import Angular.Injector (Injector())
68 | import Angular.Scope (Scope())
69 |
70 | type ElEff e r = Eff (ngel :: NgEl | e) r
71 |
72 | type Handler e = DOMEvent -> Eff e Unit
73 |
74 | foreign import data Element :: *
75 |
76 | foreign import data NgEl :: !
77 |
78 | foreign import data DeregisterHandler :: # ! -> *
79 |
80 | foreign import element
81 | " function element(el) { \
82 | \ return function(){ \
83 | \ return angular.element(el); \
84 | \ }; \
85 | \ }"
86 | :: forall e. String -> ElEff e Element
87 |
88 | foreign import addClass
89 | " function addClass(cssClasses){ \
90 | \ return function(el){ \
91 | \ return function(){ \
92 | \ return el.addClass(cssClasses); \
93 | \ }; \
94 | \ }; \
95 | \ }"
96 | :: forall e. String -> Element -> ElEff e Element
97 |
98 | foreign import after
99 | " function after(newEl){ \
100 | \ return function(el){ \
101 | \ return function(){ \
102 | \ return el.after(newEl); \
103 | \ }; \
104 | \ }; \
105 | \ }"
106 | :: forall e. Element -> Element -> ElEff e Element
107 |
108 | foreign import getAttrFn
109 | " function getAttrFn(nothing, just, name, el){ \
110 | \ return function(){ \
111 | \ var a = el.attr(name); \
112 | \ return angular.isString(a) ? just(a) : nothing; \
113 | \ }; \
114 | \ }"
115 | :: forall e. Fn4 (Maybe String)
116 | (String -> Maybe String)
117 | String
118 | Element
119 | (ElEff e (Maybe String))
120 |
121 | getAttr :: forall e. String -> Element -> ElEff e (Maybe String)
122 | getAttr = runFn4 getAttrFn Nothing Just
123 |
124 | foreign import setAttr
125 | " function setAttr(name){ \
126 | \ return function(value){ \
127 | \ return function(el){ \
128 | \ return function(){ \
129 | \ return el.attr(name, value); \
130 | \ }; \
131 | \ }; \
132 | \ }; \
133 | \ }"
134 | :: forall e. String -> String -> Element -> ElEff e Element
135 |
136 | foreign import setAllAttr
137 | " function setAllAttr(obj){ \
138 | \ return function(el){ \
139 | \ return function(){ \
140 | \ return el.attr(obj); \
141 | \ }; \
142 | \ }; \
143 | \ }"
144 | :: forall e a. { | a } -> Element -> ElEff e Element
145 |
146 | bind :: forall e f. String -> Handler f -> Element -> ElEff e (DeregisterHandler f)
147 | bind = on
148 |
149 | foreign import children
150 | " function children(el){ \
151 | \ return function(){ \
152 | \ return el.children(); \
153 | \ }; \
154 | \ }"
155 | :: forall e. Element -> ElEff e Element
156 |
157 | foreign import clone
158 | " function clone(el){ \
159 | \ return function(){ \
160 | \ return el.clone(); \
161 | \ }; \
162 | \ }"
163 | :: forall e. Element -> ElEff e Element
164 |
165 | foreign import contents
166 | " function contents(el){ \
167 | \ return function(){ \
168 | \ return el.contents(); \
169 | \ }; \
170 | \ }"
171 | :: forall e. Element -> ElEff e Element
172 |
173 | foreign import getCssFn
174 | " function getCssFn(nothing, just, name, el){ \
175 | \ return function(){ \
176 | \ var a = el.css(name); \
177 | \ return angular.isString(a) ? just(a) : nothing; \
178 | \ }; \
179 | \ }"
180 | :: forall e. Fn4 (Maybe String)
181 | (String -> Maybe String)
182 | String
183 | Element
184 | (ElEff e (Maybe String))
185 |
186 | getCss :: forall e. String -> Element -> ElEff e (Maybe String)
187 | getCss = runFn4 getCssFn Nothing Just
188 |
189 | foreign import setCss
190 | " function setCss(name){ \
191 | \ return function(value){ \
192 | \ return function(el){ \
193 | \ return function(){ \
194 | \ return el.css(name, value); \
195 | \ }; \
196 | \ }; \
197 | \ }; \
198 | \ }"
199 | :: forall e. String -> String -> Element -> ElEff e Element
200 |
201 | foreign import setAllCss
202 | " function setAllCss(obj){ \
203 | \ return function(el){ \
204 | \ return function(){ \
205 | \ return el.css(obj); \
206 | \ }; \
207 | \ }; \
208 | \ }"
209 | :: forall e a. { | a } -> Element -> ElEff e Element
210 |
211 | foreign import getDataFn
212 | " function getDataFn(nothing, just, name, el){ \
213 | \ return function(){ \
214 | \ var a = el.data(name); \
215 | \ return angular.isDefined(a) ? just(a) : nothing; \
216 | \ }; \
217 | \ }"
218 | :: forall e a. Fn4 (Maybe a)
219 | (a -> Maybe a)
220 | String
221 | Element
222 | (ElEff e (Maybe a))
223 |
224 | getData :: forall e a. String -> Element -> ElEff e (Maybe a)
225 | getData = runFn4 getDataFn Nothing Just
226 |
227 | foreign import setData
228 | " function setData(name){ \
229 | \ return function(value){ \
230 | \ return function(el){ \
231 | \ return function(){ \
232 | \ return el.data(name, value); \
233 | \ }; \
234 | \ }; \
235 | \ }; \
236 | \ }"
237 | :: forall e a. String -> a -> Element -> ElEff e Element
238 |
239 | foreign import getAllData
240 | " function getAllData(el){ \
241 | \ return function(){ \
242 | \ return el.data(); \
243 | \ }; \
244 | \ }"
245 | :: forall e a. Element -> ElEff e { | a }
246 |
247 | foreign import setAllData
248 | " function setAllData(obj){ \
249 | \ return function(el){ \
250 | \ return function(){ \
251 | \ return el.data(obj); \
252 | \ }; \
253 | \ }; \
254 | \ }"
255 | :: forall e a. { | a } -> Element -> ElEff e Element
256 |
257 | foreign import empty
258 | " function empty(el){ \
259 | \ return function(){ \
260 | \ return el.empty(); \
261 | \ }; \
262 | \ }"
263 | :: forall e. Element -> ElEff e Element
264 |
265 | foreign import eq
266 | " function eq(i){ \
267 | \ return function(el){ \
268 | \ return function(){ \
269 | \ return el.eq(i); \
270 | \ }; \
271 | \ }; \
272 | \ }"
273 | :: forall e. Number -> Element -> ElEff e Element
274 |
275 | foreign import find
276 | " function find(selector){ \
277 | \ return function(el){ \
278 | \ return function(){ \
279 | \ return el.find(selector); \
280 | \ }; \
281 | \ }; \
282 | \ }"
283 | :: forall e. Number -> Element -> ElEff e Element
284 |
285 | foreign import hasClass
286 | " function hasClass(selector){ \
287 | \ return function(el){ \
288 | \ return function(){ \
289 | \ return el.hasClass(selector); \
290 | \ }; \
291 | \ }; \
292 | \ }"
293 | :: forall e. String -> Element -> ElEff e Boolean
294 |
295 | foreign import html
296 | " function html(el){ \
297 | \ return function(){ \
298 | \ return el.html(); \
299 | \ }; \
300 | \ }"
301 | :: forall e. Element -> ElEff e String
302 |
303 | foreign import next
304 | " function next(el){ \
305 | \ return function(){ \
306 | \ return el.next(); \
307 | \ }; \
308 | \ }"
309 | :: forall e. Element -> ElEff e Element
310 |
311 | foreign import on
312 | " function on(events){ \
313 | \ return function(k){ \
314 | \ return function(el){ \
315 | \ return function(){ \
316 | \ var handler = function(event){return k(event)();}; \
317 | \ el.on(events, handler); \
318 | \ return handler; \
319 | \ }; \
320 | \ }; \
321 | \ }; \
322 | \ }"
323 | :: forall e f. String -> Handler f -> Element -> ElEff e (DeregisterHandler f)
324 |
325 | foreign import off
326 | " function off(events){ \
327 | \ return function(el){ \
328 | \ return function(){ \
329 | \ return el.off(events); \
330 | \ }; \
331 | \ }; \
332 | \ }"
333 | :: forall e f. String -> Element -> ElEff e Element
334 |
335 | foreign import offHandler
336 | " function offHandler(events){ \
337 | \ return function(k){ \
338 | \ return function(el){ \
339 | \ return function(){ \
340 | \ return el.off(events, k); \
341 | \ }; \
342 | \ }; \
343 | \ }; \
344 | \ }"
345 | :: forall e f. String -> DeregisterHandler f -> Element -> ElEff e Element
346 |
347 | foreign import one
348 | " function one(events){ \
349 | \ return function(k){ \
350 | \ return function(el){ \
351 | \ return function(){ \
352 | \ var handler = function(event){return k(event)();}; \
353 | \ el.one(events, handler); \
354 | \ return handler; \
355 | \ }; \
356 | \ }; \
357 | \ }; \
358 | \ }"
359 | :: forall e f. String -> Handler f -> Element -> ElEff e (DeregisterHandler f)
360 |
361 | foreign import parent
362 | " function parent(el){ \
363 | \ return function(){ \
364 | \ return el.parent(); \
365 | \ }; \
366 | \ }"
367 | :: forall e. Element -> ElEff e Element
368 |
369 | foreign import prepend
370 | " function prepend(newEl){ \
371 | \ return function(el){ \
372 | \ return function(){ \
373 | \ return el.prepend(newEl); \
374 | \ }; \
375 | \ }; \
376 | \ }"
377 | :: forall e. Element -> Element -> ElEff e Element
378 |
379 | foreign import getPropFn
380 | " function getPropFn(nothing, just, name, el){ \
381 | \ return function(){ \
382 | \ var a = el.prop(name); \
383 | \ return angular.isString(a) ? just(a) : nothing; \
384 | \ }; \
385 | \ }"
386 | :: forall e. Fn4 (Maybe String)
387 | (String -> Maybe String)
388 | String
389 | Element
390 | (ElEff e (Maybe String))
391 |
392 | getProp :: forall e. String -> Element -> ElEff e (Maybe String)
393 | getProp = runFn4 getPropFn Nothing Just
394 |
395 | foreign import setProp
396 | " function setProp(name){ \
397 | \ return function(value){ \
398 | \ return function(el){ \
399 | \ return function(){ \
400 | \ return el.prop(name, value); \
401 | \ }; \
402 | \ }; \
403 | \ }; \
404 | \ }"
405 | :: forall e. String -> String -> Element -> ElEff e Element
406 |
407 | foreign import setAllProp
408 | " function setAllProp(obj){ \
409 | \ return function(el){ \
410 | \ return function(){ \
411 | \ return el.prop(obj); \
412 | \ }; \
413 | \ }; \
414 | \ }"
415 | :: forall e a. { | a } -> Element -> ElEff e Element
416 |
417 | foreign import ready
418 | " function ready(k){ \
419 | \ return function(el){ \
420 | \ return function(){ \
421 | \ return el.ready(k); \
422 | \ }; \
423 | \ }; \
424 | \ }"
425 | :: forall e. Eff e Unit -> Element -> ElEff e Element
426 |
427 | foreign import remove
428 | " function remove(el){ \
429 | \ return function(){ \
430 | \ return el.remove(); \
431 | \ }; \
432 | \ }"
433 | :: forall e. Element -> ElEff e Element
434 |
435 | foreign import removeAttr
436 | " function removeAttr(name){ \
437 | \ return function(el){ \
438 | \ return function(){ \
439 | \ return el.removeAttr(name); \
440 | \ }; \
441 | \ }; \
442 | \ }"
443 | :: forall e. String -> Element -> ElEff e Element
444 |
445 | foreign import removeClass
446 | " function removeClass(name){ \
447 | \ return function(el){ \
448 | \ return function(){ \
449 | \ return el.removeClass(name); \
450 | \ }; \
451 | \ }; \
452 | \ }"
453 | :: forall e. String -> Element -> ElEff e Element
454 |
455 | foreign import removeData
456 | " function removeData(name){ \
457 | \ return function(el){ \
458 | \ return function(){ \
459 | \ return el.removeData(name); \
460 | \ }; \
461 | \ }; \
462 | \ }"
463 | :: forall e. String -> Element -> ElEff e Element
464 |
465 | foreign import replaceWith
466 | " function replaceWith(newEl){ \
467 | \ return function(el){ \
468 | \ return function(){ \
469 | \ return el.replaceWith(newEl); \
470 | \ }; \
471 | \ }; \
472 | \ }"
473 | :: forall e. Element -> Element -> ElEff e Element
474 |
475 | foreign import text
476 | " function text(el){ \
477 | \ return function(){ \
478 | \ return el.text(); \
479 | \ }; \
480 | \ }"
481 | :: forall e. Element -> ElEff e String
482 |
483 | foreign import toggleClass
484 | " function toggleClass(selector){ \
485 | \ return function(condition){ \
486 | \ return function(el){ \
487 | \ return function(){ \
488 | \ return el.toggleClass(selector, condition); \
489 | \ }; \
490 | \ }; \
491 | \ }; \
492 | \ }"
493 | :: forall e. String -> Boolean -> Element -> ElEff e Element
494 |
495 | foreign import triggerHandler
496 | " function triggerHandler(eventName){ \
497 | \ return function(eventData){ \
498 | \ return function(el){ \
499 | \ return function(){ \
500 | \ return el.triggerHandler(eventName, eventData); \
501 | \ }; \
502 | \ }; \
503 | \ }; \
504 | \ }"
505 | :: forall e a. String -> [a] -> Element -> ElEff e Element
506 |
507 | unbind :: forall e f. String -> Element -> ElEff e Element
508 | unbind = off
509 |
510 | unbindHandler :: forall e f. String -> DeregisterHandler f -> Element -> ElEff e Element
511 | unbindHandler = offHandler
512 |
513 | foreign import getValFn
514 | " function getValFn(nothing, just, el){ \
515 | \ return function(){ \
516 | \ var a = el.val(); \
517 | \ return angular.isString(a) ? just(a) : nothing; \
518 | \ }; \
519 | \ }"
520 | :: forall e. Fn3 (Maybe String)
521 | (String -> Maybe String)
522 | Element
523 | (ElEff e (Maybe String))
524 |
525 | getVal :: forall e. Element -> ElEff e (Maybe String)
526 | getVal = runFn3 getValFn Nothing Just
527 |
528 | foreign import setVal
529 | " function setVal(value){ \
530 | \ return function(el){ \
531 | \ return function(){ \
532 | \ return el.val(value); \
533 | \ }; \
534 | \ }; \
535 | \ }"
536 | :: forall e. String -> Element -> ElEff e Element
537 |
538 | foreign import wrap
539 | " function wrap(newEl){ \
540 | \ return function(el){ \
541 | \ return function(){ \
542 | \ return el.wrap(newEl); \
543 | \ }; \
544 | \ }; \
545 | \ }"
546 | :: forall e. Element -> Element -> ElEff e Element
547 |
548 | foreign import controllerFn
549 | " function controllerFn(fromMaybe, nothing, just, name, el){ \
550 | \ return function(){ \
551 | \ var a = el.controller(fromMaybe(undefined)(name)); \
552 | \ return angular.isDefined(a) ? just(a) : nothing; \
553 | \ }; \
554 | \ }"
555 | :: forall e a. Fn5 (String -> Maybe String -> String)
556 | (Maybe a)
557 | (a -> Maybe a)
558 | (Maybe String)
559 | Element
560 | (ElEff e (Maybe a))
561 |
562 | controller :: forall e a. Maybe String -> Element -> ElEff e (Maybe a)
563 | controller = runFn5 controllerFn fromMaybe Nothing Just
564 |
565 | foreign import injectorFn
566 | " function injectorFn(nothing, just, el){ \
567 | \ return function(){ \
568 | \ var a = el.injector(); \
569 | \ return angular.isDefined(a) ? just(a) : nothing; \
570 | \ }; \
571 | \ }"
572 | :: forall e a. Fn3 (Maybe Injector) (Injector -> Maybe Injector) Element (ElEff e (Maybe Injector))
573 |
574 | injector :: forall e a. Element -> ElEff e (Maybe Injector)
575 | injector = runFn3 injectorFn Nothing Just
576 |
577 | foreign import scopeFn
578 | " function scopeFn(nothing, just, el){ \
579 | \ return function(){ \
580 | \ var a = el.scope(); \
581 | \ return angular.isDefined(a) ? just(a) : nothing; \
582 | \ }; \
583 | \ }"
584 | :: forall e a. Fn3 (Maybe (Scope a)) (Scope a -> Maybe (Scope a)) Element (ElEff e (Maybe (Scope a)))
585 |
586 | scope :: forall e a. Element -> ElEff e (Maybe (Scope a))
587 | scope = runFn3 scopeFn Nothing Just
588 |
589 | foreign import isolateScopeFn
590 | " function isolateScopeFn(nothing, just, el){ \
591 | \ return function(){ \
592 | \ var a = el.isolateScope(); \
593 | \ return angular.isDefined(a) ? just(a) : nothing; \
594 | \ }; \
595 | \ }"
596 | :: forall e a. Fn3 (Maybe (Scope a)) (Scope a -> Maybe (Scope a)) Element (ElEff e (Maybe (Scope a)))
597 |
598 | isolateScope :: forall e a. Element -> ElEff e (Maybe (Scope a))
599 | isolateScope = runFn3 isolateScopeFn Nothing Just
600 |
601 | foreign import inheritedData
602 | " function inheritedData(el){ \
603 | \ return function(){ \
604 | \ return el.inheritedData(); \
605 | \ }; \
606 | \ }"
607 | :: forall e a. Element -> ElEff e { | a }
608 |
609 | foreign import bangbangFn
610 | " function bangbangFn(nothing, just, el, i) { \
611 | \ var r = el[i]; \
612 | \ return angular.isDefined(r) ? just(r) : nothing; \
613 | \ }"
614 | :: Fn4 (Maybe HTMLElement) (HTMLElement -> Maybe HTMLElement) Element Number (Maybe HTMLElement)
615 |
616 | infixl 8 !!
617 |
618 | (!!) :: Element -> Number -> Maybe HTMLElement
619 | (!!) = runFn4 bangbangFn Nothing Just
620 |
--------------------------------------------------------------------------------
/src/Angular/FormController.purs:
--------------------------------------------------------------------------------
1 | module Angular.FormController
2 | ( FormController()
3 | , FormEff()
4 | , NgForm()
5 | , addControl
6 | , removeControl
7 | , setValidity
8 | , setDirty
9 | , setPristine
10 | , pristine
11 | , dirty
12 | , valid
13 | , invalid
14 | , error
15 | ) where
16 |
17 | import Control.Monad.Eff
18 |
19 | import Angular.NgModelController (NgModelController(), ValidationErrorKey())
20 |
21 | foreign import data FormController :: *
22 |
23 | foreign import data NgForm :: !
24 |
25 | type FormEff e r = Eff (ngform :: NgForm | e) r
26 |
27 | foreign import addControl
28 | " function addControl(control){ \
29 | \ return function($ctrl){ \
30 | \ return function(){ \
31 | \ return $ctrl.$addControl(control); \
32 | \ }; \
33 | \ }; \
34 | \ } "
35 | :: forall e a. NgModelController a -> FormController -> FormEff e Unit
36 |
37 | foreign import removeControl
38 | " function removeControl(control){ \
39 | \ return function($ctrl){ \
40 | \ return function(){ \
41 | \ return $ctrl.$removeControl(control); \
42 | \ }; \
43 | \ }; \
44 | \ } "
45 | :: forall e a. NgModelController a -> FormController -> FormEff e Unit
46 |
47 | foreign import setValidity
48 | " function setValidity(key){ \
49 | \ return function(isValid){ \
50 | \ return function(control){ \
51 | \ return function($ctrl){ \
52 | \ return function(){ \
53 | \ return $ctrl.$setValidity(key, isValid, control, $ctrl); \
54 | \ }; \
55 | \ }; \
56 | \ }; \
57 | \ }; \
58 | \ } "
59 | :: forall e a. ValidationErrorKey -> Boolean -> NgModelController a -> FormController -> FormEff e Unit
60 |
61 | foreign import setDirty
62 | " function setDirty($ctrl){ \
63 | \ return function(){ \
64 | \ return $ctrl.$setDirty(); \
65 | \ }; \
66 | \ } "
67 | :: forall e. FormController -> FormEff e Unit
68 |
69 | foreign import setPristine
70 | " function setPristine($ctrl){ \
71 | \ return function(){ \
72 | \ return $ctrl.$setPristine(); \
73 | \ }; \
74 | \ } "
75 | :: forall e. FormController -> FormEff e Unit
76 |
77 | foreign import pristine
78 | " function pristine($ctrl){ \
79 | \ return function(){ \
80 | \ return $ctrl.$pristine; \
81 | \ }; \
82 | \ } "
83 | :: forall e. FormController -> FormEff e Boolean
84 |
85 | foreign import dirty
86 | " function dirty($ctrl){ \
87 | \ return function(){ \
88 | \ return $ctrl.$dirty; \
89 | \ }; \
90 | \ } "
91 | :: forall e. FormController -> FormEff e Boolean
92 |
93 | foreign import valid
94 | " function valid($ctrl){ \
95 | \ return function(){ \
96 | \ return $ctrl.$valid; \
97 | \ }; \
98 | \ } "
99 | :: forall e. FormController -> FormEff e Boolean
100 |
101 | foreign import invalid
102 | " function invalid($ctrl){ \
103 | \ return function(){ \
104 | \ return $ctrl.$invalid; \
105 | \ }; \
106 | \ } "
107 | :: forall e. FormController -> FormEff e Boolean
108 |
109 | foreign import error
110 | " function error($ctrl){ \
111 | \ return function(){ \
112 | \ return $ctrl.$error; \
113 | \ }; \
114 | \ } "
115 | :: forall e a. FormController -> FormEff e { | a }
116 |
--------------------------------------------------------------------------------
/src/Angular/Http.purs:
--------------------------------------------------------------------------------
1 | module Angular.Http
2 | ( Http()
3 | , HttpResponse()
4 | , Response()
5 | , Config()
6 | , config
7 | , http
8 | , get
9 | , get'
10 | , del
11 | , del'
12 | , head
13 | , head'
14 | , jsonp
15 | , jsonp'
16 | , post
17 | , post'
18 | , put
19 | , put'
20 | ) where
21 |
22 | import Data.Either
23 | import Data.Function
24 | import Data.Maybe
25 | import Data.Tuple
26 |
27 | import qualified Data.DOM.Simple.Ajax as D
28 |
29 | import Angular.Cache (Cache())
30 | import qualified Angular.Http.Internal as I
31 | import Angular.Http.Types
32 | import Angular.Promise (Promise(), then1')
33 |
34 | foreign import data Http :: *
35 |
36 | type HttpResponse e r a b c d = HttpEff e (Promise I.ForeignResponse (Response r a b c d))
37 |
38 | type ForeignHttpResponse e = HttpEff e (Promise I.ForeignResponse I.ForeignResponse)
39 |
40 | type Response r a b c d
41 | = { "data" :: D.HttpData r
42 | , status :: Status
43 | , headers :: [String] -> String
44 | , config :: Config a b c d
45 | , statusText :: String
46 | }
47 |
48 | type Config a b c d
49 | = { method :: D.HttpMethod
50 | , url :: D.Url
51 | , params :: { | a }
52 | , "data" :: RequestData b
53 | , headers :: Headers
54 | , xsrfHeaderName :: String
55 | , xsrfCookieName :: String
56 | , cache :: Either Boolean Cache
57 | , timeout :: Either Number (Promise c d)
58 | , withCredentials :: Boolean
59 | , responseType :: D.ResponseType
60 | }
61 |
62 | xsrfHeaderName = "X-XSRF-TOKEN"
63 |
64 | xsrfCookieName = "XSRF-TOKEN"
65 |
66 | config :: forall a b c d. Config a b c d
67 | config = { method: D.GET
68 | , url: "/"
69 | , params: runFn0 emptyParams
70 | , "data": NoRequestData
71 | , headers: Headers []
72 | , xsrfHeaderName: xsrfHeaderName
73 | , xsrfCookieName: xsrfCookieName
74 | , cache: Left false
75 | , timeout: Left 0
76 | , withCredentials: false
77 | , responseType: D.Default }
78 |
79 | http :: forall e r a b c d. Config a b c d -> Http -> HttpResponse e r a b c d
80 | http c h = (then1' foreignResponse) <$> (foreignConfig c >>= runFn2 httpFn h)
81 |
82 | get :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
83 | get u = runHttpFn' D.GET u config
84 |
85 | get' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
86 | get' = runHttpFn' D.GET
87 |
88 | del :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
89 | del u = runHttpFn' D.DELETE u config
90 |
91 | del' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
92 | del' = runHttpFn' D.DELETE
93 |
94 | head :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
95 | head u = runHttpFn' D.HEAD u config
96 |
97 | head' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
98 | head' = runHttpFn' D.HEAD
99 |
100 | jsonp :: forall e r a b c d. D.Url -> Http -> HttpResponse e r a b c d
101 | jsonp u = runHttpFn' D.JSONP u config
102 |
103 | jsonp' :: forall e r a b c d. D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
104 | jsonp' = runHttpFn' D.JSONP
105 |
106 | post :: forall e r a b c d. D.Url -> RequestData b -> Http -> HttpResponse e r a b c d
107 | post u d = runHttpFn'' D.POST u d config
108 |
109 | post' :: forall e r a b c d. D.Url -> RequestData b -> Config a b c d -> Http -> HttpResponse e r a b c d
110 | post' = runHttpFn'' D.POST
111 |
112 | put :: forall e r a b c d. D.Url -> RequestData b -> Http -> HttpResponse e r a b c d
113 | put u d = runHttpFn'' D.PUT u d config
114 |
115 | put' :: forall e r a b c d. D.Url -> RequestData b -> Config a b c d -> Http -> HttpResponse e r a b c d
116 | put' = runHttpFn'' D.PUT
117 |
118 | runHttpFn' :: forall e r a b c d. D.HttpMethod -> D.Url -> Config a b c d -> Http -> HttpResponse e r a b c d
119 | runHttpFn' m u c h = do
120 | conf <- foreignConfig c
121 | res <- runFn4 httpFn' (show m) u conf h
122 | return $ then1' foreignResponse res
123 |
124 | runHttpFn'' :: forall e r a b c d. D.HttpMethod -> D.Url -> RequestData b -> Config a b c d -> Http -> HttpResponse e r a b c d
125 | runHttpFn'' m u d c h = do
126 | conf <- foreignConfig c
127 | res <- runFn5 httpFn'' (show m) u (writeRequestData d) conf h
128 | return $ then1' foreignResponse res
129 |
130 | foreignConfig :: forall e a b c d. Config a b c d -> HttpEff e I.ForeignConfig
131 | foreignConfig conf = do
132 | c <- I.foreignConfig
133 | I.setConfigMethod conf.method c
134 | I.setConfigUrl conf.url c
135 | I.setConfigParams conf.params c
136 | I.setConfigRequestData conf."data" c
137 | I.setConfigHeaders conf.headers c
138 | I.setConfigXsrfHeaderName conf.xsrfHeaderName c
139 | I.setConfigXsrfCookieName conf.xsrfCookieName c
140 | I.setConfigCache conf.cache c
141 | I.setConfigTimeout conf.timeout c
142 | I.setConfigWithCredentials conf.withCredentials c
143 | I.setConfigResponseType conf.responseType c
144 | return c
145 |
146 | foreignResponse :: forall r a b c d. I.ForeignResponse -> Response r a b c d
147 | foreignResponse res =
148 | let conf = I.getResponseConfig res
149 | in { "data": I.getResponseData (I.getConfigResponseType conf) res
150 | , status: I.getResponseStatus res
151 | , headers: I.getResponseHeaders res
152 | , config: { method: I.getConfigMethod conf
153 | , url: I.getConfigUrl conf
154 | , params: I.getConfigParams conf
155 | , "data": I.getConfigRequestData conf
156 | , headers: I.getConfigHeaders conf
157 | , xsrfHeaderName: I.getConfigXsrfHeaderName conf
158 | , xsrfCookieName: I.getConfigXsrfCookieName conf
159 | , cache: I.getConfigCache conf
160 | , timeout: I.getConfigTimeout conf
161 | , withCredentials: I.getConfigWithCredentials conf
162 | , responseType: I.getConfigResponseType conf
163 | }
164 | , statusText: I.getResponseStatusText res
165 | }
166 |
167 | foreign import httpFn
168 | " function httpFn($http, conf){ \
169 | \ return function(){ \
170 | \ return $http(conf); \
171 | \ }; \
172 | \ } "
173 | :: forall e. Fn2 Http I.ForeignConfig (ForeignHttpResponse e)
174 |
175 | foreign import httpFn'
176 | " function httpFn$prime(method, url, conf, $http){ \
177 | \ return function(){ \
178 | \ return $http[method.toLowerCase()](url, conf); \
179 | \ } \
180 | \ } "
181 | :: forall e. Fn4 String
182 | D.Url
183 | I.ForeignConfig
184 | Http
185 | (ForeignHttpResponse e)
186 |
187 | foreign import httpFn''
188 | " function httpFn$prime$prime(method, url, data, conf, $http){ \
189 | \ return function(){ \
190 | \ return $http[method.toLowerCase()](url, data, conf); \
191 | \ } \
192 | \ } "
193 | :: forall e. Fn5 String
194 | D.Url
195 | ForeignRequestData
196 | I.ForeignConfig
197 | Http
198 | (ForeignHttpResponse e)
199 |
200 | foreign import emptyParams
201 | " function emptyParams(){ \
202 | \ return {}; \
203 | \ } "
204 | :: forall a. Fn0 { | a}
205 |
--------------------------------------------------------------------------------
/src/Angular/Http/Internal.purs:
--------------------------------------------------------------------------------
1 | module Angular.Http.Internal
2 | ( ForeignConfig()
3 | , ForeignResponse()
4 | , setConfigMethod
5 | , getConfigMethod
6 | , setConfigUrl
7 | , getConfigUrl
8 | , setConfigParams
9 | , getConfigParams
10 | , setConfigRequestData
11 | , getConfigRequestData
12 | , setConfigHeaders
13 | , getConfigHeaders
14 | , setConfigXsrfHeaderName
15 | , getConfigXsrfHeaderName
16 | , setConfigXsrfCookieName
17 | , getConfigXsrfCookieName
18 | , setConfigCache
19 | , getConfigCache
20 | , setConfigTimeout
21 | , getConfigTimeout
22 | , setConfigWithCredentials
23 | , getConfigWithCredentials
24 | , setConfigResponseType
25 | , getConfigResponseType
26 | , getResponseData
27 | , getResponseStatus
28 | , getResponseHeaders
29 | , getResponseConfig
30 | , getResponseStatusText
31 | , foreignConfig
32 | ) where
33 |
34 | import Control.Monad.Eff
35 | import Control.Monad.Error
36 | import Data.Either
37 | import Data.Foldable (for_)
38 | import Data.Function
39 | import Data.Tuple
40 |
41 | import qualified Data.DOM.Simple.Ajax as D
42 |
43 | import Angular.Cache
44 | import Angular.Http.Types
45 | import Angular.Promise (Promise())
46 |
47 | foreign import data ForeignConfig :: *
48 |
49 | foreign import data ForeignResponse :: *
50 |
51 | foreign import unimplementedForeignResponse
52 | """
53 | function unimplementedForeignResponse(){
54 | return {
55 | };
56 | }
57 | """ :: ForeignResponse
58 |
59 | instance errorForeignResponse :: Error ForeignResponse where
60 | noMsg = unimplementedForeignResponse
61 | strMsg = \_ -> unimplementedForeignResponse
62 |
63 | setConfigMethod :: forall e. D.HttpMethod -> ForeignConfig -> HttpEff e Unit
64 | setConfigMethod m = runFn3 setConfigPropFn "method" (show m)
65 |
66 | getConfigMethod:: ForeignConfig -> D.HttpMethod
67 | getConfigMethod c = readMethod $ runFn2 getConfigPropFn "method" c
68 |
69 | setConfigUrl :: forall e. D.Url -> ForeignConfig -> HttpEff e Unit
70 | setConfigUrl = runFn3 setConfigPropFn "url"
71 |
72 | getConfigUrl :: ForeignConfig -> D.Url
73 | getConfigUrl = runFn2 getConfigPropFn "url"
74 |
75 | setConfigParams :: forall e a. { | a } -> ForeignConfig -> HttpEff e Unit
76 | setConfigParams = runFn3 setConfigPropFn "params"
77 |
78 | getConfigParams :: forall a. ForeignConfig -> { | a}
79 | getConfigParams = runFn2 getConfigPropFn "params"
80 |
81 | setConfigRequestData :: forall e a. RequestData a -> ForeignConfig -> HttpEff e Unit
82 | setConfigRequestData =
83 | let k = "data"
84 | in cataRequestData (runFn3 setConfigPropFn k (runFn0 undefinedFn))
85 | (runFn3 setConfigPropFn k)
86 | (runFn3 setConfigPropFn k)
87 |
88 | getConfigRequestData :: forall e a. ForeignConfig -> RequestData a
89 | getConfigRequestData c = runFn2 readRequestDataFn { noRequestData: NoRequestData
90 | , stringRequestData: StringRequestData
91 | , objectRequestData: ObjectRequestData } $ runFn2 getConfigPropFn "data" c
92 |
93 | setConfigHeaders :: forall e. Headers -> ForeignConfig -> HttpEff e Unit
94 | setConfigHeaders (Headers h) c =
95 | let k = "headers" in for_ h $ \a ->
96 | case a of
97 | Tuple l (Left v) -> runFn4 setInnerConfigPropFn k l v c
98 | Tuple l (Right v) -> runFn4 setInnerConfigPropFn k l v c
99 |
100 | getConfigHeaders :: ForeignConfig -> Headers
101 | getConfigHeaders c = runFn4 readHeadersFn Left Right Tuple $ runFn2 getConfigPropFn "headers" c
102 |
103 | setConfigXsrfHeaderName :: forall e. String -> ForeignConfig -> HttpEff e Unit
104 | setConfigXsrfHeaderName = runFn3 setConfigPropFn "xsrfHeaderName"
105 |
106 | getConfigXsrfHeaderName :: ForeignConfig -> String
107 | getConfigXsrfHeaderName = runFn2 getConfigPropFn "xsrfHeaderName"
108 |
109 | setConfigXsrfCookieName :: forall e. String -> ForeignConfig -> HttpEff e Unit
110 | setConfigXsrfCookieName = runFn3 setConfigPropFn "xsrfCookieName"
111 |
112 | getConfigXsrfCookieName :: ForeignConfig -> String
113 | getConfigXsrfCookieName = runFn2 getConfigPropFn "xsrfCookieName"
114 |
115 | setConfigCache :: forall e. Either Boolean Cache -> ForeignConfig -> HttpEff e Unit
116 | setConfigCache = let k = "cache" in either (runFn3 setConfigPropFn k) (runFn3 setConfigPropFn k)
117 |
118 | getConfigCache :: ForeignConfig -> (Either Boolean Cache)
119 | getConfigCache c = runFn3 readCacheFn Left Right $ runFn2 getConfigPropFn "cache" c
120 |
121 | setConfigTimeout :: forall e a b. Either Number (Promise a b) -> ForeignConfig -> HttpEff e Unit
122 | setConfigTimeout = let k = "timeout" in either (runFn3 setConfigPropFn k) (runFn3 setConfigPropFn k)
123 |
124 | getConfigTimeout :: forall a b. ForeignConfig -> Either Number (Promise a b)
125 | getConfigTimeout c = runFn3 readTimeoutFn Left Right $ runFn2 getConfigPropFn "timeout" c
126 |
127 | setConfigWithCredentials :: forall e. Boolean -> ForeignConfig -> HttpEff e Unit
128 | setConfigWithCredentials = runFn3 setConfigPropFn "withCredentials"
129 |
130 | getConfigWithCredentials :: ForeignConfig -> Boolean
131 | getConfigWithCredentials = runFn2 getConfigPropFn "withCredentials"
132 |
133 | setConfigResponseType :: forall e. D.ResponseType -> ForeignConfig -> HttpEff e Unit
134 | setConfigResponseType r = runFn3 setConfigPropFn "responseType" (show r)
135 |
136 | getConfigResponseType :: ForeignConfig -> D.ResponseType
137 | getConfigResponseType c = readResponseType $ runFn2 getConfigPropFn "responseType" c
138 |
139 | getResponseData :: forall a. D.ResponseType -> ForeignResponse -> D.HttpData a
140 | getResponseData t = get t <<< runFn2 getResponsePropFn "data" where
141 | get D.Default = readResponseData D.TextData
142 | get D.ArrayBuffer = readResponseData D.ArrayBufferData
143 | get D.Blob = readResponseData D.BlobData
144 | get D.Document = readResponseData D.DocumentData
145 | get D.Json = readResponseData D.JsonData
146 | get D.Text = readResponseData D.TextData
147 | get D.MozBlob = readResponseData D.BlobData
148 | get D.MozChunkedText = readResponseData D.TextData
149 | get D.MozChunkedArrayBuffer = readResponseData D.ArrayBufferData
150 |
151 | getResponseStatus :: ForeignResponse -> Status
152 | getResponseStatus r = readStatus $ runFn2 getResponsePropFn "status" r
153 |
154 | getResponseHeaders :: ForeignResponse -> ([String] -> String)
155 | getResponseHeaders = runFn2 getResponsePropFn "headers"
156 |
157 | getResponseConfig :: ForeignResponse -> ForeignConfig
158 | getResponseConfig = runFn2 getResponsePropFn "config"
159 |
160 | getResponseStatusText :: ForeignResponse -> String
161 | getResponseStatusText = runFn2 getResponsePropFn "statusText"
162 |
163 | foreign import foreignConfig
164 | " function foreignConfig(){ \
165 | \ return {}; \
166 | \ } "
167 | :: forall e. HttpEff e ForeignConfig
168 |
169 | foreign import setConfigPropFn
170 | " function setConfigPropFn(k, v, conf){ \
171 | \ return function(){ \
172 | \ conf[k] = v; \
173 | \ }; \
174 | \ } "
175 | :: forall e a. Fn3 String a ForeignConfig (HttpEff e Unit)
176 |
177 | foreign import setInnerConfigPropFn
178 | " function setInnerConfigPropFn(k1, k2, v, conf){ \
179 | \ return function(){ \
180 | \ if (angular.isUndefined(conf[k1])) { \
181 | \ conf[k1] = {}; \
182 | \ } \
183 | \ conf[k1][k2] = v; \
184 | \ }; \
185 | \ } "
186 | :: forall e a. Fn4 String String a ForeignConfig (HttpEff e Unit)
187 |
188 | foreign import getConfigPropFn
189 | " function getConfigPropFn(k, conf){ \
190 | \ return conf[k]; \
191 | \ } "
192 | :: forall a. Fn2 String ForeignConfig a
193 |
194 | foreign import getResponsePropFn
195 | " function getResponsePropFn(k, response){ \
196 | \ return response[k]; \
197 | \ } "
198 | :: forall a. Fn2 String ForeignResponse a
199 |
200 | foreign import undefinedFn
201 | " function undefinedFn(){ \
202 | \ return undefined; \
203 | \ } "
204 | :: forall a. Fn0 a
205 |
--------------------------------------------------------------------------------
/src/Angular/Http/Types.purs:
--------------------------------------------------------------------------------
1 | module Angular.Http.Types
2 | ( NgHttp()
3 | , HttpEff()
4 | , Status(..)
5 | , RequestData(..)
6 | , Header()
7 | , Headers(..)
8 | , RequestDataFn()
9 | , ForeignRequestData()
10 | , ForeignResponseData()
11 | , ForeignCache()
12 | , ForeignHeaders()
13 | , ForeignTimeout()
14 | , stringHeader
15 | , fnHeader
16 | , readCacheFn
17 | , readRequestDataFn
18 | , readResponseData
19 | , readHeadersFn
20 | , readMethod
21 | , readResponseType
22 | , readStatus
23 | , readTimeoutFn
24 | , cataRequestData
25 | , writeRequestData
26 | ) where
27 |
28 | import Control.Monad.Eff
29 | import Data.Either
30 | import Data.Function
31 | import Data.Tuple
32 |
33 | import Angular.Cache (Cache())
34 | import Angular.Promise (Promise())
35 |
36 | import qualified Data.DOM.Simple.Types as D
37 | import qualified Data.DOM.Simple.Ajax as D
38 |
39 | foreign import data NgHttp :: !
40 |
41 | foreign import data ForeignRequestData :: *
42 |
43 | foreign import data ForeignResponseData :: *
44 |
45 | foreign import data ForeignHeaders :: *
46 |
47 | foreign import data ForeignCache :: *
48 |
49 | foreign import data ForeignTimeout :: *
50 |
51 | type HttpEff e r = Eff (nghttp :: NgHttp | e) r
52 |
53 | data Status = OK | Created | NoContent | BadRequest | Unauthorized | Forbidden | NotFound | InternalServerError | OtherStatus Number
54 |
55 | data RequestData a
56 | = NoRequestData
57 | | StringRequestData String
58 | | ObjectRequestData a
59 |
60 | type Header = Tuple String (Either String (Unit -> String))
61 |
62 | newtype Headers = Headers [Header]
63 |
64 | stringHeader :: String -> String -> Header
65 | stringHeader k v = Tuple k $ Left v
66 |
67 | fnHeader :: String -> (Unit -> String) -> Header
68 | fnHeader k v = Tuple k $ Right v
69 |
70 | type RequestDataFn a
71 | = { noRequestData :: RequestData a
72 | , stringRequestData :: String -> RequestData a
73 | , objectRequestData :: a -> RequestData a
74 | }
75 |
76 | foreign import readRequestDataFn
77 | " function readRequestDataFn(fn, data){ \
78 | \ if (angular.isUndefined(data)) return fn.noRequestData; \
79 | \ else if (angular.isString(data)) return fn.stringRequestData(data); \
80 | \ else return fn.objectRequestData(data); \
81 | \ } "
82 | :: forall a. Fn2 (RequestDataFn a) ForeignRequestData (RequestData a)
83 |
84 | cataRequestData :: forall a b
85 | . b
86 | -> (String -> b)
87 | -> (a -> b)
88 | -> RequestData a
89 | -> b
90 | cataRequestData f g h d =
91 | case d of
92 | NoRequestData -> f
93 | StringRequestData a -> g a
94 | ObjectRequestData a -> h a
95 |
96 | foreign import writeRequestData
97 | " function writeRequestData(data){ \
98 | \ return cataRequestData(undefined) \
99 | \ (angular.identity) \
100 | \ (angular.identity) \
101 | \ (data); \
102 | \ } "
103 | :: forall a. RequestData a -> ForeignRequestData
104 |
105 | foreign import readResponseDataFn
106 | " function readResponseDataFn(no, fn, data){ \
107 | \ if (angular.isUndefined(data)) return no; \
108 | \ else return fn(data); \
109 | \ } "
110 | :: forall a d. Fn3 (D.HttpData a) (d -> D.HttpData a) ForeignResponseData (D.HttpData a)
111 |
112 | readResponseData :: forall a d. (d -> D.HttpData a) -> ForeignResponseData -> D.HttpData a
113 | readResponseData = runFn3 readResponseDataFn D.NoData
114 |
115 | foreign import readHeadersFn
116 | " function readHeadersFn(left, right, tuple, headers){ \
117 | \ if (angular.isUndefined(headers)) return []; \
118 | \ else { \
119 | \ var arr = []; \
120 | \ angular.forEach(headers, function(v, k){ \
121 | \ arr.push(tuple(k)(angular.isString(v) ? left(v) : right(v))); \
122 | \ }); \
123 | \ return arr; \
124 | \ } \
125 | \ } "
126 | :: forall a b. Fn4 (String -> Either String (Unit -> String))
127 | ((Unit -> String) -> Either String (Unit -> String))
128 | (String -> Either String (Unit -> String) -> Header)
129 | ForeignHeaders
130 | Headers
131 |
132 | readStatus :: Number -> Status
133 | readStatus s =
134 | case s of
135 | 200 -> OK
136 | 201 -> Created
137 | 204 -> NoContent
138 | 400 -> BadRequest
139 | 401 -> Unauthorized
140 | 403 -> Forbidden
141 | 404 -> NotFound
142 | 500 -> InternalServerError
143 | a -> OtherStatus a
144 |
145 | readMethod :: String -> D.HttpMethod
146 | readMethod m =
147 | case m of
148 | "GET" -> D.GET
149 | "POST" -> D.POST
150 | "PUT" -> D.PUT
151 | "DELETE" -> D.DELETE
152 | "PATCH" -> D.PATCH
153 | "HEAD" -> D.HEAD
154 | "OPTIONS" -> D.OPTIONS
155 | "JSONP" -> D.JSONP
156 |
157 | readResponseType :: String -> D.ResponseType
158 | readResponseType r =
159 | case r of
160 | "" -> D.Default
161 | "arraybuffer" -> D.ArrayBuffer
162 | "blob" -> D.Blob
163 | "document" -> D.Document
164 | "json" -> D.Json
165 | "text" -> D.Text
166 | "moz-blob" -> D.MozBlob
167 | "moz-chunked-test" -> D.MozChunkedText
168 | "moz-chunked-arraybuffer" -> D.MozChunkedArrayBuffer
169 |
170 | foreign import readCacheFn
171 | " function readCacheFn(left, right, cache){ \
172 | \ return (cache === true || cache === false) ? left(cache) : right(cache); \
173 | \ } "
174 | :: Fn3 (Boolean -> Either Boolean Cache)
175 | (Cache -> Either Boolean Cache)
176 | ForeignCache
177 | (Either Boolean Cache)
178 |
179 | foreign import readTimeoutFn
180 | " function readTimeoutFn(left, right, timeout){ \
181 | \ return angular.isNumber(timeout) ? left(timeout) : right(timeout); \
182 | \ } "
183 | :: forall a b. Fn3 (Number -> Either Number (Promise a b))
184 | (Promise a b -> Either Number (Promise a b))
185 | ForeignTimeout
186 | (Either Number (Promise a b))
187 |
--------------------------------------------------------------------------------
/src/Angular/Injector.purs:
--------------------------------------------------------------------------------
1 | module Angular.Injector
2 | ( Injector()
3 | , InjEff()
4 | , NgInj()
5 | , get
6 | , invoke
7 | , has
8 | , instantiate
9 | , annotate
10 | , injector
11 | ) where
12 |
13 | import Control.Monad.Eff
14 | import Data.Function
15 | import Data.Maybe
16 |
17 | foreign import data Injector :: *
18 |
19 | foreign import data NgInj :: !
20 |
21 | type InjEff e a = Eff (nginj :: NgInj | e) a
22 |
23 | get :: forall e a. String -> Injector -> InjEff e a
24 | get = runFn2 getFn
25 |
26 | invoke :: forall e r a b c. a -> Maybe { | b } -> Maybe { | c } -> Injector -> InjEff e r
27 | invoke = runFn5 invokeFn maybe
28 |
29 | has :: forall e. String -> Injector -> InjEff e Boolean
30 | has = runFn2 hasFn
31 |
32 | instantiate :: forall e r a b. a -> Maybe { | b } -> Injector -> InjEff e r
33 | instantiate = runFn4 instantiateFn maybe
34 |
35 | annotate :: forall e a. a -> Injector -> InjEff e [String]
36 | annotate = runFn2 annotateFn
37 |
38 | foreign import injector
39 | " function injector(modules){ \
40 | \ return function(){ \
41 | \ return angular.injector(modules); \
42 | \ }; \
43 | \ } "
44 | :: forall e. [String] -> InjEff e Injector
45 |
46 | foreign import getFn
47 | " function getFn(name, $injector){ \
48 | \ return function(){ \
49 | \ return $injector.get(name); \
50 | \ } \
51 | \ } "
52 | :: forall e a. Fn2 String Injector (InjEff e a)
53 |
54 | foreign import invokeFn
55 | " function invokeFn(maybe, fn, self, locals, $injector){ \
56 | \ return function(){ \
57 | \ return $injector.invoke(fn, \
58 | \ maybe(undefined)(angular.identity)(self), \
59 | \ maybe(undefined)(angular.identity)(locals)); \
60 | \ } \
61 | \ } "
62 | :: forall e r s t u a b c. Fn5 (t -> (u -> t) -> Maybe s -> t) a (Maybe { | b }) (Maybe { | c }) Injector (InjEff e r)
63 |
64 | foreign import hasFn
65 | " function hasFn(name, $injector){ \
66 | \ return function(){ \
67 | \ return $injector.get(name); \
68 | \ } \
69 | \ } "
70 | :: forall e. Fn2 String Injector (InjEff e Boolean)
71 |
72 | foreign import instantiateFn
73 | " function instantiateFn(maybe, type, locals, $injector){ \
74 | \ return function(){ \
75 | \ return $injector.instantiate(type, maybe(undefined)(angular.identity)(locals)); \
76 | \ } \
77 | \ } "
78 | :: forall e r s t u a b. Fn4 (t -> (u -> t) -> Maybe s -> t) a (Maybe { | b }) Injector (InjEff e r)
79 |
80 | foreign import annotateFn
81 | " function annotateFn(fn, $injector){ \
82 | \ return function(){ \
83 | \ return $injector.annotate(fn); \
84 | \ } \
85 | \ } "
86 | :: forall e a. Fn2 a Injector (InjEff e [String])
87 |
--------------------------------------------------------------------------------
/src/Angular/Interpolate.purs:
--------------------------------------------------------------------------------
1 | module Angular.Interpolate
2 | ( NgInterpolate()
3 | , Interpolate()
4 | , InterpolateEff()
5 | , Expression()
6 | , interpolate
7 | , startSymbol
8 | , endSymbol
9 | ) where
10 |
11 | import Control.Monad.Eff
12 | import Data.Function
13 | import Data.Maybe
14 |
15 | foreign import data Interpolate :: *
16 |
17 | foreign import data NgInterpolate :: !
18 |
19 | type Expression a = { | a } -> String
20 |
21 | type InterpolateEff e a = Eff (nginterpolate :: NgInterpolate | e) a
22 |
23 | foreign import interpolateFn
24 | " function interpolateFn(fromMaybe, text, mustHaveExpression, trustedContext, $interpolate){ \
25 | \ return function(){ \
26 | \ return $interpolate(text, \
27 | \ fromMaybe(undefined)(mustHaveExpression), \
28 | \ fromMaybe(undefined)(trustedContext)); \
29 | \ }; \
30 | \ } "
31 | :: forall e a. Fn5 (forall a. a -> Maybe a -> a)
32 | String
33 | (Maybe Boolean)
34 | (Maybe String)
35 | Interpolate
36 | (InterpolateEff e (Expression a))
37 |
38 | interpolate :: forall e a. String -> Maybe Boolean -> Maybe String -> Interpolate -> InterpolateEff e (Expression a)
39 | interpolate = runFn5 interpolateFn fromMaybe
40 |
41 | foreign import startSymbol
42 | " function startSymbol($interpolate){ \
43 | \ return $interpolate.startSymbol(); \
44 | \ } "
45 | :: Interpolate -> String
46 |
47 | foreign import endSymbol
48 | " function endSymbol($interpolate){ \
49 | \ return $interpolate.endSymbol(); \
50 | \ } "
51 | :: Interpolate -> String
52 |
--------------------------------------------------------------------------------
/src/Angular/Interval.purs:
--------------------------------------------------------------------------------
1 | module Angular.Interval
2 | ( Interval()
3 | , NgInterval()
4 | , IntervalEff()
5 | , IntervalPromise()
6 | , interval
7 | , interval'
8 | , interval''
9 | , intervalk
10 | , cancel
11 | ) where
12 |
13 | import Control.Monad.Eff
14 | import Data.Function
15 | import Data.Maybe
16 |
17 | import Angular.Promise (Promise())
18 |
19 | foreign import data Interval :: *
20 |
21 | foreign import data NgInterval :: !
22 |
23 | type IntervalEff e r = Eff (nginterval :: NgInterval | e) r
24 |
25 | type IntervalPromise = Promise Unit Number
26 |
27 | foreign import intervalFn
28 | " function intervalFn(fromMaybe, fn, delay, count, invokeApply, $interval){ \
29 | \ return function(){ \
30 | \ return $interval(fn, delay, fromMaybe(undefined)(count), fromMaybe(undefined)(invokeApply)); \
31 | \ }; \
32 | \ } "
33 | :: forall e f r. Fn6 (forall a. a -> Maybe a -> a)
34 | (Eff f r)
35 | Number
36 | (Maybe Number)
37 | (Maybe Boolean)
38 | Interval
39 | (IntervalEff e IntervalPromise)
40 |
41 | interval :: forall e f r. Eff f r -> Number -> Number -> Boolean -> Interval -> IntervalEff e IntervalPromise
42 | interval fn delay count invoke = runFn6 intervalFn fromMaybe fn delay (Just count) (Just invoke)
43 |
44 | interval' :: forall e f r. Eff f r -> Number -> Number -> Interval -> IntervalEff e IntervalPromise
45 | interval' fn delay count = runFn6 intervalFn fromMaybe fn delay (Just count) Nothing
46 |
47 | interval'' :: forall e f r. Eff f r -> Number -> Interval -> IntervalEff e IntervalPromise
48 | interval'' fn delay = runFn6 intervalFn fromMaybe fn delay Nothing Nothing
49 |
50 | intervalk :: forall e f r. Number -> Number -> Boolean -> Interval -> Eff f r -> IntervalEff e IntervalPromise
51 | intervalk delay count invoke interval fn = runFn6 intervalFn fromMaybe fn delay (Just count) (Just invoke) interval
52 |
53 | foreign import cancelFn
54 | " function cancelFn(promise, $interval){ \
55 | \ return function(){ \
56 | \ return $interval.cancel(promise); \
57 | \ }; \
58 | \ } "
59 | :: forall e. Fn2 IntervalPromise
60 | Interval
61 | (IntervalEff e Boolean)
62 |
63 | cancel :: forall e. IntervalPromise -> Interval -> IntervalEff e Boolean
64 | cancel = runFn2 cancelFn
65 |
--------------------------------------------------------------------------------
/src/Angular/Location.purs:
--------------------------------------------------------------------------------
1 | module Angular.Location
2 | ( Location()
3 | , LocEff()
4 | , NgLoc()
5 | , getPath
6 | , setPath
7 | ) where
8 |
9 | import Control.Monad.Eff
10 |
11 | foreign import data Location :: *
12 |
13 | foreign import data NgLoc :: !
14 |
15 | type LocEff e a = Eff (ngloc :: NgLoc | e) a
16 |
17 | foreign import getPath
18 | " function getPath(loc){ \
19 | \ return function(){ \
20 | \ return loc.path(); \
21 | \ }; \
22 | \ }"
23 | :: forall e. Location -> LocEff e String
24 |
25 | foreign import setPath
26 | " function setPath(path){ \
27 | \ return function(loc){ \
28 | \ return function(){ \
29 | \ return loc.path(path); \
30 | \ }; \
31 | \ }; \
32 | \ }"
33 | :: forall e. String -> Location -> LocEff e String
34 |
--------------------------------------------------------------------------------
/src/Angular/Log.purs:
--------------------------------------------------------------------------------
1 | module Angular.Log
2 | ( NgLog()
3 | , Log()
4 | , LogEff()
5 | , log
6 | , info
7 | , warn
8 | , error
9 | , debug
10 | ) where
11 |
12 | import Control.Monad.Eff
13 | import Data.Function
14 |
15 | foreign import data Log :: *
16 |
17 | foreign import data NgLog :: !
18 |
19 | type LogEff e = Eff (nglog :: NgLog | e) Unit
20 |
21 | foreign import logFn
22 | " function logFn(fn, message, $log){ \
23 | \ return function(){ \
24 | \ return $log[fn](message); \
25 | \ }; \
26 | \ } "
27 | :: forall e a. Fn3 String a Log (LogEff e)
28 |
29 | log :: forall e a. a -> Log -> LogEff e
30 | log = runFn3 logFn "log"
31 |
32 | info :: forall e a. a -> Log -> LogEff e
33 | info = runFn3 logFn "info"
34 |
35 | warn :: forall e a. a -> Log -> LogEff e
36 | warn = runFn3 logFn "warn"
37 |
38 | error :: forall e a. a -> Log -> LogEff e
39 | error = runFn3 logFn "error"
40 |
41 | debug :: forall e a. a -> Log -> LogEff e
42 | debug = runFn3 logFn "debug"
43 |
--------------------------------------------------------------------------------
/src/Angular/Module.purs:
--------------------------------------------------------------------------------
1 | module Angular.Module
2 | ( Module()
3 | , NgReadModule()
4 | , NgWriteModule()
5 | , NgRegisterToModule()
6 | , ReadEff()
7 | , WriteEff()
8 | , RegisterEff()
9 | , ngmodule
10 | , ngmodule'
11 | , provider
12 | , factory
13 | , service
14 | , value
15 | , constant
16 | , animation
17 | , filter
18 | , controller
19 | , directive
20 | , config
21 | , run
22 | ) where
23 |
24 | import Control.Monad.Eff
25 | import Data.Function
26 |
27 | foreign import data Module :: *
28 |
29 | foreign import data NgReadModule :: !
30 |
31 | foreign import data NgWriteModule :: !
32 |
33 | foreign import data NgRegisterToModule :: !
34 |
35 | type ReadEff e = Eff (ngrmod :: NgReadModule | e) Module
36 |
37 | type WriteEff e = Eff (ngwmod :: NgWriteModule | e) Module
38 |
39 | type RegisterEff e = Eff (nggmod :: NgRegisterToModule | e) Module
40 |
41 | ngmodule :: forall e. String -> ReadEff e
42 | ngmodule = readModuleFn
43 |
44 | ngmodule' :: forall e. String -> [String] -> WriteEff e
45 | ngmodule' = runFn2 writeModuleFn
46 |
47 | provider :: forall e a. String -> a -> Module -> RegisterEff e
48 | provider = runFn4 registerNamedToModuleFn "provider"
49 |
50 | factory :: forall e a. String -> a -> Module -> RegisterEff e
51 | factory = runFn4 registerNamedToModuleFn "factory"
52 |
53 | service :: forall e a. String -> a -> Module -> RegisterEff e
54 | service = runFn4 registerNamedToModuleFn "service"
55 |
56 | value :: forall e a. String -> a -> Module -> RegisterEff e
57 | value = runFn4 registerNamedToModuleFn "value"
58 |
59 | constant :: forall e a. String -> a -> Module -> RegisterEff e
60 | constant = runFn4 registerNamedToModuleFn "constant"
61 |
62 | animation :: forall e a. String -> a -> Module -> RegisterEff e
63 | animation = runFn4 registerNamedToModuleFn "animation"
64 |
65 | filter :: forall e a. String -> a -> Module -> RegisterEff e
66 | filter = runFn4 registerNamedToModuleFn "filter"
67 |
68 | controller :: forall e a. String -> a -> Module -> RegisterEff e
69 | controller = runFn4 registerNamedToModuleFn "controller"
70 |
71 | directive :: forall e a. String -> a -> Module -> RegisterEff e
72 | directive = runFn4 registerNamedToModuleFn "directive"
73 |
74 | config :: forall e a. a -> Module -> RegisterEff e
75 | config = runFn3 registerUnnamedToModuleFn "config"
76 |
77 | run :: forall e a. a -> Module -> RegisterEff e
78 | run = runFn3 registerUnnamedToModuleFn "run"
79 |
80 | foreign import readModuleFn
81 | "function readModuleFn(name){\
82 | \ return function(){\
83 | \ return angular.module(name);\
84 | \ };\
85 | \}" :: forall e. String -> ReadEff e
86 |
87 | foreign import writeModuleFn
88 | "function writeModuleFn(name, modules){\
89 | \ return function(){\
90 | \ return angular.module(name, modules);\
91 | \ };\
92 | \}" :: forall e. Fn2 String [String] (WriteEff e)
93 |
94 | foreign import registerNamedToModuleFn
95 | "function registerNamedToModuleFn(type, name, a, module){\
96 | \ return function(){\
97 | \ return module[type](name, a);\
98 | \ };\
99 | \}" :: forall e a. Fn4 String String a Module (RegisterEff e)
100 |
101 | foreign import registerUnnamedToModuleFn
102 | "function registerUnnamedToModuleFn(type, a, module){\
103 | \ return function(){\
104 | \ return module[type](a);\
105 | \ };\
106 | \}" :: forall e a. Fn3 String a Module (RegisterEff e)
107 |
--------------------------------------------------------------------------------
/src/Angular/NgModelController.purs:
--------------------------------------------------------------------------------
1 | module Angular.NgModelController
2 | ( NgModelController()
3 | , NgModel()
4 | , NgModelEff()
5 | , Parser()
6 | , Formatter()
7 | , ValidationErrorKey()
8 | , render
9 | , setRender
10 | , isEmpty
11 | , setIsEmpty
12 | , setValidity
13 | , setPristine
14 | , setViewValue
15 | , viewValue
16 | , modelValue
17 | , setModelValue
18 | , appendParsers
19 | , prependParsers
20 | , appendFormatters
21 | , prependFormatters
22 | , appendViewChangeListeners
23 | , prependViewChangeListeners
24 | , error
25 | , pristine
26 | , dirty
27 | , valid
28 | , invalid
29 | ) where
30 |
31 | import Control.Monad.Eff
32 | import Data.Function
33 | import Data.Maybe
34 |
35 | foreign import data NgModelController :: * -> *
36 |
37 | foreign import data NgModel :: !
38 |
39 | type NgModelEff e r = Eff (ngmodel :: NgModel | e) r
40 |
41 | type ValidationErrorKey = String
42 |
43 | type Parser a = String -> Maybe a
44 |
45 | type Formatter a = a -> String
46 |
47 | foreign import render
48 | " function render($ctrl){ \
49 | \ return function(){ \
50 | \ return $ctrl.$render(); \
51 | \ }; \
52 | \ } "
53 | :: forall e a. NgModelController a -> NgModelEff e Unit
54 |
55 | foreign import setRender
56 | " function setRender(render){ \
57 | \ return function($ctrl){ \
58 | \ $ctrl.$render = render; \
59 | \ return {}; \
60 | \ }; \
61 | \ } "
62 | :: forall e a. NgModelEff e Unit -> NgModelController a -> NgModelEff e Unit
63 |
64 | foreign import isEmpty
65 | " function isEmpty(value){ \
66 | \ return function($ctrl){ \
67 | \ return $ctrl.$isEmpty(value); \
68 | \ }; \
69 | \ } "
70 | :: forall e a. a -> NgModelController a -> NgModelEff e Boolean
71 |
72 | foreign import setIsEmpty
73 | " function setIsEmpty(isEmpty){ \
74 | \ return function($ctrl){ \
75 | \ $ctrl.$isEmpty = function(a){return isEmpty(a)();}; \
76 | \ return $ctrl; \
77 | \ }; \
78 | \ } "
79 | :: forall e a b. (b -> NgModelEff e Boolean) -> NgModelController a -> NgModelEff e (NgModelController b)
80 |
81 | foreign import setValidity
82 | " function setValidity(validationErrorKey){ \
83 | \ return function(isValid){ \
84 | \ return function($ctrl){ \
85 | \ return $ctrl.$setValidity(validationErrorKey, isValid); \
86 | \ }; \
87 | \ }; \
88 | \ } "
89 | :: forall e a. ValidationErrorKey -> Boolean -> NgModelController a -> NgModelEff e Unit
90 |
91 | foreign import setPristine
92 | " function setPristine($ctrl){ \
93 | \ return function(){ \
94 | \ return $ctrl.$setPristine(); \
95 | \ }; \
96 | \ } "
97 | :: forall e a. NgModelController a -> NgModelEff e Unit
98 |
99 | foreign import setViewValue
100 | " function setViewValue(value){ \
101 | \ return function($ctrl){ \
102 | \ return function(){ \
103 | \ return $ctrl.$setViewValue(value); \
104 | \ }; \
105 | \ }; \
106 | \ } "
107 | :: forall e a. String -> NgModelController a -> NgModelEff e Unit
108 |
109 | foreign import viewValue
110 | " function viewValue($ctrl){ \
111 | \ return function(){ \
112 | \ return $ctrl.$viewValue; \
113 | \ }; \
114 | \ } "
115 | :: forall e a. NgModelController a -> NgModelEff e String
116 |
117 | foreign import modelValue
118 | " function modelValue($ctrl){ \
119 | \ return function(){ \
120 | \ return $ctrl.$modelValue; \
121 | \ }; \
122 | \ } "
123 | :: forall e a. NgModelController a -> NgModelEff e a
124 |
125 | foreign import setModelValue
126 | " function setModelValue(value){ \
127 | \ return function($ctrl){ \
128 | \ return function(){ \
129 | \ $ctrl.$modelValue = value; \
130 | \ return $ctrl; \
131 | \ }; \
132 | \ }; \
133 | \ } "
134 | :: forall e a b. b -> NgModelController a -> NgModelEff e (NgModelController b)
135 |
136 | foreign import appendParsersFn
137 | " function appendParsersFn(fromMaybe, parsers, $ctrl){ \
138 | \ return function(){ \
139 | \ var as = []; \
140 | \ angular.forEach(parsers, function(p){ \
141 | \ as.push(function(v){ \
142 | \ return fromMaybe(undefined)(p(v)); \
143 | \ }); \
144 | \ }); \
145 | \ $ctrl.$parsers.push.apply($ctrl.$parsers, as); \
146 | \ return {}; \
147 | \ }; \
148 | \ } "
149 | :: forall e a. Fn3 (a -> Maybe a -> a)
150 | [Parser a]
151 | (NgModelController a)
152 | (NgModelEff e Unit)
153 |
154 | appendParsers :: forall e a. [Parser a] -> NgModelController a -> NgModelEff e Unit
155 | appendParsers = runFn3 appendParsersFn fromMaybe
156 |
157 | foreign import prependParsersFn
158 | " function prependParsersFn(fromMaybe, parsers, $ctrl){ \
159 | \ return function(){ \
160 | \ var as = []; \
161 | \ angular.forEach(parsers, function(p){ \
162 | \ as.push(function(v){ \
163 | \ return fromMaybe(undefined)(p(v)); \
164 | \ }); \
165 | \ }); \
166 | \ $ctrl.$parsers.unshift.apply($ctrl.$parsers, as); \
167 | \ return {}; \
168 | \ }; \
169 | \ } "
170 | :: forall e a. Fn3 (a -> Maybe a -> a)
171 | [Parser a]
172 | (NgModelController a)
173 | (NgModelEff e Unit)
174 |
175 | prependParsers :: forall e a. [Parser a] -> NgModelController a -> NgModelEff e Unit
176 | prependParsers = runFn3 prependParsersFn fromMaybe
177 |
178 | foreign import appendFormatters
179 | " function appendFormatters(formatters){ \
180 | \ return function($ctrl){ \
181 | \ return function(){ \
182 | \ $ctrl.$formatters.push.apply($ctrl.$formatters, formatters); \
183 | \ return {}; \
184 | \ }; \
185 | \ }; \
186 | \ } "
187 | :: forall e a. [Formatter a] -> NgModelController a -> NgModelEff e Unit
188 |
189 | foreign import prependFormatters
190 | " function prependFormatters(formatters){ \
191 | \ return function($ctrl){ \
192 | \ return function(){ \
193 | \ $ctrl.$formatters.unshift.apply($ctrl.$formatters, formatters); \
194 | \ return {}; \
195 | \ }; \
196 | \ }; \
197 | \ } "
198 | :: forall e a. [Formatter a] -> NgModelController a -> NgModelEff e Unit
199 |
200 | foreign import appendViewChangeListeners
201 | " function appendViewChangeListeners(listeners){ \
202 | \ return function($ctrl){ \
203 | \ return function(){ \
204 | \ $ctrl.$viewChangeListeners.push.apply($ctrl.$viewChangeListeners, listeners); \
205 | \ return {}; \
206 | \ }; \
207 | \ }; \
208 | \ } "
209 | :: forall e a. [Eff e Unit] -> NgModelController a -> NgModelEff e Unit
210 |
211 | foreign import prependViewChangeListeners
212 | " function prependViewChangeListeners(listeners){ \
213 | \ return function($ctrl){ \
214 | \ return function(){ \
215 | \ $ctrl.$viewChangeListeners.unshift.apply($ctrl.$viewChangeListeners, listeners); \
216 | \ return {}; \
217 | \ }; \
218 | \ }; \
219 | \ } "
220 | :: forall e a. [Eff e Unit] -> NgModelController a -> NgModelEff e Unit
221 |
222 | foreign import error
223 | " function error($ctrl){ \
224 | \ return function(){ \
225 | \ return $ctrl.$error; \
226 | \ }; \
227 | \ } "
228 | :: forall e a b. NgModelController a -> NgModelEff e { | b }
229 |
230 | foreign import pristine
231 | " function pristine($ctrl){ \
232 | \ return function(){ \
233 | \ return $ctrl.$pristine; \
234 | \ }; \
235 | \ } "
236 | :: forall e a. NgModelController a -> NgModelEff e Boolean
237 |
238 | foreign import dirty
239 | " function dirty($ctrl){ \
240 | \ return function(){ \
241 | \ return $ctrl.$dirty; \
242 | \ }; \
243 | \ } "
244 | :: forall e a. NgModelController a -> NgModelEff e Boolean
245 |
246 | foreign import valid
247 | " function valid($ctrl){ \
248 | \ return function(){ \
249 | \ return $ctrl.$valid; \
250 | \ }; \
251 | \ } "
252 | :: forall e a. NgModelController a -> NgModelEff e Boolean
253 |
254 | foreign import invalid
255 | " function invalid($ctrl){ \
256 | \ return function(){ \
257 | \ return $ctrl.$invalid; \
258 | \ }; \
259 | \ } "
260 | :: forall e a. NgModelController a -> NgModelEff e Boolean
261 |
--------------------------------------------------------------------------------
/src/Angular/Parse.purs:
--------------------------------------------------------------------------------
1 | module Angular.Parse
2 | ( NgParse()
3 | , Parse()
4 | , ParseEff()
5 | , Expression()
6 | , Getter()
7 | , Setter()
8 | , parse
9 | , get
10 | , assign
11 | , literal
12 | , constant
13 | , set
14 | ) where
15 |
16 | import Control.Monad.Eff
17 | import Data.Function
18 | import Data.Maybe
19 |
20 | foreign import data Parse :: *
21 |
22 | foreign import data NgParse :: !
23 |
24 | foreign import data Getter :: * -> *
25 |
26 | foreign import data Setter :: * -> *
27 |
28 | type ParseEff e r = Eff (ngparse :: NgParse | e) r
29 |
30 | type Expression = String
31 |
32 | foreign import parseFn
33 | " function parseFn(expression, $parse){ \
34 | \ return function(){ \
35 | \ return $parse(expression); \
36 | \ }; \
37 | \ } "
38 | :: forall e a. Fn2 Expression Parse (ParseEff e (Getter a))
39 |
40 | parse :: forall e a. Expression -> Parse -> ParseEff e (Getter a)
41 | parse = runFn2 parseFn
42 |
43 | foreign import getFn
44 | " function getFn(context, locals, getter){ \
45 | \ return function(){ \
46 | \ return getter(context, locals); \
47 | \ }; \
48 | \ } "
49 | :: forall e a b c. Fn3 { | a } { | b } (Getter c) (ParseEff e c)
50 |
51 | get :: forall e a b c. { | a } -> { | b } -> Getter c -> ParseEff e c
52 | get = runFn3 getFn
53 |
54 | foreign import assignFn
55 | " function assignFn(nothing, just, getter){ \
56 | \ var fn = getter.assign; \
57 | \ return angular.isFunction(fn) ? just(fn) : nothing; \
58 | \ } "
59 | :: forall a. Fn3 (Maybe (Setter a))
60 | (Setter a -> Maybe (Setter a))
61 | (Getter a)
62 | (Maybe (Setter a))
63 |
64 | assign :: forall a. Getter a -> Maybe (Setter a)
65 | assign = runFn3 assignFn Nothing Just
66 |
67 | foreign import literal
68 | " function literal(getter){ \
69 | \ return getter.literal; \
70 | \ } "
71 | :: forall a. Getter a -> Boolean
72 |
73 | foreign import constant
74 | " function constant(getter){ \
75 | \ return getter.constant; \
76 | \ } "
77 | :: forall a. Getter a -> Boolean
78 |
79 | foreign import setFn
80 | " function setFn(context, value, setter){ \
81 | \ return function(){ \
82 | \ return setter(context, value); \
83 | \ }; \
84 | \ } "
85 | :: forall e a b. Fn3 { | a } b (Setter b) (ParseEff e b)
86 |
87 | set :: forall e a b. { | a } -> b -> Setter b -> ParseEff e b
88 | set = runFn3 setFn
89 |
--------------------------------------------------------------------------------
/src/Angular/Promise.purs:
--------------------------------------------------------------------------------
1 | module Angular.Promise
2 | ( Promise()
3 | , PromiseEC()
4 | , then1
5 | , then1'
6 | , then2
7 | , then2'
8 | , then3
9 | , then3'
10 | , catch
11 | , finally
12 | , liftPromiseEC
13 | , runPromiseEC
14 | ) where
15 |
16 | import Control.Monad.Cont.Trans (ContT(..), runContT)
17 | import Control.Monad.Eff
18 | import Control.Monad.Error (Error)
19 | import Control.Monad.Error.Trans (ErrorT(..), runErrorT)
20 | import Control.Monad.Trans (lift)
21 |
22 | import Data.Either (Either(Right, Left))
23 | import Data.Function
24 |
25 | foreign import data Promise :: * -> * -> *
26 |
27 | type PromiseEC e a b = ErrorT a (ContT Unit (Eff e)) b
28 |
29 | foreign import then1Fn
30 | """
31 | function then1Fn(f, fa){
32 | return fa['then'](f);
33 | }
34 | """ :: forall a b c d. Fn2 (b -> c) (Promise a b) (Promise a d)
35 |
36 | then1 :: forall a b c. (b -> Promise a c) -> Promise a b -> Promise a c
37 | then1 = runFn2 then1Fn
38 |
39 | then1' :: forall a b c. (b -> c) -> Promise a b -> Promise a c
40 | then1' = runFn2 then1Fn
41 |
42 | foreign import then2Fn
43 | """
44 | function then2Fn(f, g, fa){
45 | return fa['then'](f, g);
46 | }
47 | """ :: forall s t a b c d. Fn3 (b -> d) (a -> c) (Promise a b) (Promise s t)
48 |
49 | then2 :: forall a b c d. (b -> Promise c d) -> (a -> Promise c d) -> Promise a b -> Promise c d
50 | then2 = runFn3 then2Fn
51 |
52 | then2' :: forall a b c d. (b -> d) -> (a -> c) -> Promise a b -> Promise c d
53 | then2' = runFn3 then2Fn
54 |
55 | foreign import then3Fn
56 | """
57 | function then3Fn(f, g, h, fa){
58 | return fa['then'](f, g, function(a){
59 | return h(a)();
60 | });
61 | }
62 | """ :: forall e q r s t a b c d. Fn4 (b -> d)
63 | (a -> c)
64 | (s -> Eff e t)
65 | (Promise a b)
66 | (Promise q r)
67 |
68 | then3 :: forall e s t a b c d. (b -> Promise c d) -> (a -> Promise c d) -> (s -> Eff e t) -> Promise a b -> Promise c d
69 | then3 = runFn4 then3Fn
70 |
71 | then3' :: forall e s t a b c d. (b -> d) -> (a -> c) -> (s -> Eff e t) -> Promise a b -> Promise c d
72 | then3' = runFn4 then3Fn
73 |
74 | foreign import catchFn
75 | """
76 | function catchFn(f, fa){
77 | return fa['catch'](f);
78 | }
79 | """ :: forall a b c d. Fn2 (a -> Promise c d) (Promise a b) (Promise c d)
80 |
81 | catch :: forall a b c d. (a -> Promise c d) -> Promise a b -> Promise c d
82 | catch = runFn2 catchFn
83 |
84 | foreign import finallyFn
85 | """
86 | function finallyFn(f, fa){
87 | return fa['finally'](f);
88 | }
89 | """ :: forall e r a b. Fn2 (Eff e r) (Promise a b) (Promise a b)
90 |
91 | finally :: forall e r a b. Eff e r -> Promise a b -> Promise a b
92 | finally = runFn2 finallyFn
93 |
94 | foreign import then2ECFn
95 | """
96 | function then2ECFn(f, g, fa){
97 | return function(){
98 | var run = function(k){
99 | return function(a){
100 | return k(a)();
101 | };
102 | };
103 | fa['then'](run(f), run(g));
104 | };
105 | }
106 | """ :: forall e a b c. Fn3 (b -> c) (a -> c) (Promise a b) (Eff e Unit)
107 |
108 | promiseEC :: forall e a b. Promise a b -> PromiseEC e a b
109 | promiseEC = ErrorT <<< ContT <<< cb
110 | where
111 | cb fa k = runFn3 then2ECFn (k <<< Right) (k <<< Left) fa
112 |
113 | liftPromiseEC :: forall e a b. (Error a) => Eff e (Promise a b) -> PromiseEC e a b
114 | liftPromiseEC fa = (lift $ lift fa) >>= promiseEC
115 |
116 | runPromiseEC :: forall e a b. PromiseEC e a b -> (Either a b -> Eff e Unit) -> Eff e Unit
117 | runPromiseEC = runContT <<< runErrorT
118 |
--------------------------------------------------------------------------------
/src/Angular/Q.purs:
--------------------------------------------------------------------------------
1 | module Angular.Q
2 | ( Q()
3 | , QEff()
4 | , NgQ()
5 | , defer
6 | , reject
7 | , when
8 | , all
9 | ) where
10 |
11 | import Control.Monad.Eff
12 | import Data.Function
13 |
14 | import Angular.Deferred (Deferred())
15 | import Angular.Promise (Promise())
16 |
17 | foreign import data Q :: *
18 |
19 | foreign import data NgQ :: !
20 |
21 | type QEff e r = Eff (ngq :: NgQ | e) r
22 |
23 | foreign import defer
24 | " function defer($q){ \
25 | \ return function(){ \
26 | \ return $q.defer(); \
27 | \ }; \
28 | \ } "
29 | :: forall e a b. Q -> (QEff e (Deferred a b))
30 |
31 | foreign import rejectFn
32 | " function rejectFn(e, $q){ \
33 | \ return function(){ \
34 | \ return $q.reject(e); \
35 | \ }; \
36 | \ } "
37 | :: forall e a b. Fn2 a Q (QEff e (Promise a b))
38 |
39 | reject :: forall e a b. a -> Q -> QEff e (Promise a b)
40 | reject = runFn2 rejectFn
41 |
42 | foreign import whenFn
43 | " function whenFn(a, $q){ \
44 | \ return function(){ \
45 | \ return $q.when(a); \
46 | \ }; \
47 | \ } "
48 | :: forall e a b. Fn2 b Q (QEff e (Promise a b))
49 |
50 | when :: forall e a b. b -> Q -> QEff e (Promise a b)
51 | when = runFn2 whenFn
52 |
53 | foreign import allFn
54 | " function allFn(a, $q){ \
55 | \ return function(){ \
56 | \ return $q.all(a); \
57 | \ }; \
58 | \ } "
59 | :: forall e a b. Fn2 [Promise a b] Q (QEff e (Promise b [a]))
60 |
61 | all :: forall e a b. [Promise a b] -> Q -> QEff e (Promise b [a])
62 | all = runFn2 allFn
63 |
--------------------------------------------------------------------------------
/src/Angular/Scope.purs:
--------------------------------------------------------------------------------
1 | module Angular.Scope
2 | ( Scope()
3 | , ScopeEff()
4 | , NgReadScope()
5 | , NgWriteScope()
6 | , NgScope()
7 | , ReadEff()
8 | , WriteEff()
9 | , ReadWriteEff()
10 | , WatchListener()
11 | , Event()
12 | , ApplyExpr(..)
13 | , WatchDeregistration()
14 | , OnDeregistration()
15 | , readScope
16 | , writeScope
17 | , extendScope
18 | , modifyScope
19 | , newScope
20 | , watch
21 | , watchCollection
22 | , digest
23 | , destroy
24 | , evalSync
25 | , evalAsync
26 | , applyExpr
27 | , stringApplyExpr
28 | , defaultApplyExpr
29 | , apply
30 | , on
31 | , emit
32 | , broadcast
33 | , deregisterWatch
34 | , deregisterOn
35 | , id
36 | , root
37 | , parent
38 | ) where
39 |
40 | import Prelude (Unit(), ($))
41 | import Control.Monad.Eff
42 | import Control.Monad.Eff.Unsafe
43 | import Data.Maybe
44 | import Data.Function (Fn2(), Fn3(), Fn4(), Fn5(), runFn2, runFn3, runFn4, runFn5)
45 |
46 | type WatchListener e a b = a -> a -> Scope b -> Eff e Unit
47 |
48 | type Event e a b
49 | = { targetScope :: Scope a
50 | , currentScope :: Scope b
51 | , name :: String
52 | , stopPropagation :: Eff e Unit
53 | , preventDefault :: Eff e Unit
54 | , defaultPrevented :: Boolean
55 | }
56 |
57 | data ApplyExpr e r a
58 | = DefaultApplyExpr
59 | | StringApplyExpr String
60 | | FnApplyExpr (Scope a -> Eff e r)
61 |
62 | foreign import data Scope :: # * -> *
63 |
64 | foreign import data WatchDeregistration :: *
65 |
66 | foreign import data OnDeregistration :: *
67 |
68 | foreign import data NgReadScope :: !
69 |
70 | foreign import data NgWriteScope :: !
71 |
72 | foreign import data NgScope :: !
73 |
74 | type ReadEff e a = Eff (ngrscope :: NgReadScope | e) { | a }
75 |
76 | type WriteEff e = Eff (ngwscope :: NgWriteScope | e) Unit
77 |
78 | type ReadWriteEff e r = Eff (ngrscope :: NgReadScope, ngwscope :: NgWriteScope | e) r
79 |
80 | type ScopeEff e r = Eff (ngscope :: NgScope | e) r
81 |
82 | modifyScope :: forall e a b. ({ | a} -> ReadWriteEff e { | b }) -> Scope a -> ReadWriteEff e Unit
83 | modifyScope k s = do
84 | s' <- readScope s
85 | w <- unsafeInterleaveEff $ k s'
86 | extendScope w s
87 |
88 | foreign import readScope
89 | "function readScope($scope){\
90 | \ return function(){\
91 | \ return $scope;\
92 | \ };\
93 | \}" :: forall e a. Scope a -> ReadEff e a
94 |
95 | foreign import writeScopeFn
96 | "function writeScopeFn(prop, value, $scope){\
97 | \ return function(){\
98 | \ $scope[prop] = value;\
99 | \ };\
100 | \}" :: forall e a b. Fn3 String b (Scope a) (WriteEff e)
101 |
102 | writeScope :: forall e a b. String -> b -> Scope a -> WriteEff e
103 | writeScope = runFn3 writeScopeFn
104 |
105 | foreign import extendScopeFn
106 | "function extendScopeFn(obj, $scope){\
107 | \ return function(){\
108 | \ angular.extend($scope, obj);\
109 | \ };\
110 | \}" :: forall e a b. Fn2 { | b } (Scope a) (WriteEff e)
111 |
112 | extendScope :: forall e a b. { | b } -> Scope a -> WriteEff e
113 | extendScope = runFn2 extendScopeFn
114 |
115 | foreign import newScopeFn
116 | " function newScopeFn(isolate, $scope){ \
117 | \ return $scope.$new(isolate); \
118 | \ }"
119 | :: forall e a b. Fn2 Boolean (Scope a) (ScopeEff e (Scope b))
120 |
121 | newScope :: forall e a b. Boolean -> Scope a -> ScopeEff e (Scope b)
122 | newScope = runFn2 newScopeFn
123 |
124 | foreign import watchFn
125 | " function watchFn(maybe, exp, listener, objEq, $scope){ \
126 | \ return maybe(function(){return $scope.$watch(exp, undefined, objEq);}) \
127 | \ (function(k){return function(){return $scope.$watch(exp, function(a1,a2,$scope){k(a1)(a2)($scope)()}, objEq);}}) \
128 | \ (listener); \
129 | \ }"
130 | :: forall e a b. Fn5 (Eff e WatchDeregistration
131 | -> (WatchListener e a b -> Eff e WatchDeregistration)
132 | -> Maybe (WatchListener e a b)
133 | -> Eff e WatchDeregistration)
134 | String
135 | (Maybe (WatchListener e a b))
136 | Boolean
137 | (Scope b)
138 | (ScopeEff e WatchDeregistration)
139 |
140 | watch :: forall e a b. String -> Maybe (WatchListener e a b) -> Boolean -> Scope b -> ScopeEff e WatchDeregistration
141 | watch = runFn5 watchFn maybe
142 |
143 | foreign import watchCollectionFn
144 | " function watchCollectionFn(exp, listener, $scope){ \
145 | \ return function(){ \
146 | \ return $scope.$watchCollection(exp, function(a1,a2,$scope){ \
147 | \ return listener(a1)(a2)($scope)(); \
148 | \ }); \
149 | \ }; \
150 | \ }"
151 | :: forall e a b. Fn3 String (WatchListener e a b) (Scope b) (ScopeEff e WatchDeregistration)
152 |
153 | watchCollection :: forall e a b. String -> WatchListener e a b -> Scope b -> ScopeEff e WatchDeregistration
154 | watchCollection = runFn3 watchCollectionFn
155 |
156 | foreign import digest
157 | " function digest($scope){ \
158 | \ return function(){ \
159 | \ return $scope.$digest(); \
160 | \ }; \
161 | \ }"
162 | :: forall e a. Scope a -> ScopeEff e Unit
163 |
164 | foreign import destroy
165 | " function destroy($scope){ \
166 | \ return function(){ \
167 | \ return $scope.$destroy(); \
168 | \ }; \
169 | \ }"
170 | :: forall e a. Scope a -> ScopeEff e Unit
171 |
172 | foreign import evalSyncFn
173 | " function evalSyncFn(maybe, expr, locals, $scope){ \
174 | \ return maybe(function(){return $scope.$eval(undefined, maybe(undefined)(angular.identity)(locals));}) \
175 | \ (function(k){return function(){return $scope.$eval(function($scope){return k($scope)();}, \
176 | \ maybe(undefined)(angular.identity)(locals));}}) \
177 | \ (expr); \
178 | \ } "
179 | :: forall e r s t a b c. Fn4 (t -> (s -> t) -> Maybe s -> t)
180 | (Maybe (Scope a -> Eff e r))
181 | (Maybe { | b })
182 | (Scope a)
183 | (ScopeEff e r)
184 |
185 | evalSync :: forall e r a b. Maybe (Scope a -> Eff e r) -> Maybe { | b } -> Scope a -> ScopeEff e r
186 | evalSync = runFn4 evalSyncFn maybe
187 |
188 | foreign import evalAsyncFn
189 | " function evalAsyncFn(maybe, expr, scope){ \
190 | \ return maybe(function(){return scope.$evalAsync();}) \
191 | \ (function(k){return function(){return scope.$evalAsync(function(scope){return k(scope)();});}}) \
192 | \ (expr); \
193 | \ } "
194 | :: forall e r s t a b. Fn3 (t -> (s -> t) -> Maybe s -> t)
195 | (Maybe (Scope a -> Eff e r))
196 | (Scope a)
197 | (ScopeEff e r)
198 |
199 | evalAsync :: forall e r a. Maybe (Scope a -> Eff e r) -> Scope a -> ScopeEff e r
200 | evalAsync = runFn3 evalAsyncFn maybe
201 |
202 | defaultApplyExpr :: forall e r a. ApplyExpr e r a
203 | defaultApplyExpr = DefaultApplyExpr
204 |
205 | stringApplyExpr :: forall e r a. String -> ApplyExpr e r a
206 | stringApplyExpr = StringApplyExpr
207 |
208 | applyExpr :: forall e r a. (Scope a -> Eff e r) -> ApplyExpr e r a
209 | applyExpr = FnApplyExpr
210 |
211 | cataApply :: forall e r a b
212 | . b
213 | -> (String -> b)
214 | -> ((Scope a -> Eff e r) -> b)
215 | -> ApplyExpr e r a
216 | -> b
217 | cataApply f g h a =
218 | case a of
219 | DefaultApplyExpr -> f
220 | StringApplyExpr a -> g a
221 | FnApplyExpr a -> h a
222 |
223 | foreign import applyFn
224 | " function applyFn(expr, $scope){ \
225 | \ return function(){ \
226 | \ return $scope.$apply(cataApply(undefined) \
227 | \ (angular.identity) \
228 | \ (function(a){return a(scope)();}) \
229 | \ (expr)); \
230 | \ }; \
231 | \ }"
232 | :: forall e r a. Fn2 (ApplyExpr e r a) (Scope a) (ScopeEff e r)
233 |
234 | apply :: forall e r a. ApplyExpr e r a -> Scope a -> ScopeEff e r
235 | apply = runFn2 applyFn
236 |
237 | foreign import onFn
238 | " function onFn(name, listener, $scope){ \
239 | \ return function(){ \
240 | \ return $scope.$on(name, function(event, arg){ \
241 | \ return listener(event)(arg)(); \
242 | \ }); \
243 | \ }; \
244 | \ }"
245 | :: forall e a b c. Fn3 String
246 | (Event e a b -> c -> Eff e Unit)
247 | (Scope b)
248 | (ScopeEff e OnDeregistration)
249 |
250 | on :: forall e a b c. String -> (Event e a b -> c -> Eff e Unit) -> Scope b -> ScopeEff e OnDeregistration
251 | on = runFn3 onFn
252 |
253 | foreign import emitFn
254 | " function emitFn(name, arg, $scope){ \
255 | \ return function(){ \
256 | \ return $scope.$emit(name, arg); \
257 | \ }; \
258 | \ } "
259 | :: forall e a b c. Fn3 String a (Scope b) (ScopeEff e (Event e b c))
260 |
261 | emit :: forall e a b c. String -> a -> Scope b -> ScopeEff e (Event e b c)
262 | emit = runFn3 emitFn
263 |
264 | foreign import broadcastFn
265 | " function broadcastFn(name, arg, $scope){ \
266 | \ return function(){ \
267 | \ return $scope.$broadcast(name, arg); \
268 | \ }; \
269 | \ } "
270 | :: forall e a b c. Fn3 String a (Scope b) (ScopeEff e (Event e b c))
271 |
272 | broadcast :: forall e a b c. String -> a -> Scope b -> ScopeEff e (Event e b c)
273 | broadcast = runFn3 broadcastFn
274 |
275 | foreign import deregisterWatch "function deregisterWatch(dereg){return dereg();}" :: WatchDeregistration -> Unit
276 |
277 | foreign import deregisterOn "function deregisterOn(dereg){return dereg();}" :: OnDeregistration -> Unit
278 |
279 | foreign import id "function id(scope){return scope.$id;}" :: forall a. Scope a -> String
280 |
281 | foreign import root "function root(scope){return scope.$root;}" :: forall a b. Scope a -> Scope b
282 |
283 | foreign import parentFn
284 | " function parentFn(nothing, just, scope){ \
285 | \ var a = scope.$parent; \
286 | \ return a ? just(a) : nothing; \
287 | \ }"
288 | :: forall a b. Fn3 (Maybe (Scope b)) (Scope b -> Maybe (Scope b)) (Scope a) (Maybe (Scope b))
289 |
290 | parent :: forall a b. Scope a -> Maybe (Scope b)
291 | parent = runFn3 parentFn Nothing Just
292 |
--------------------------------------------------------------------------------
/src/Angular/This.purs:
--------------------------------------------------------------------------------
1 | module Angular.This
2 | ( This()
3 | , ReadEff()
4 | , WriteEff()
5 | , ReadWriteEff()
6 | , NgReadThis()
7 | , NgWriteThis()
8 | , readThis
9 | , writeThis
10 | , extendThis
11 | , modifyThis
12 | ) where
13 |
14 | import Control.Monad.Eff
15 | import Control.Monad.Eff.Unsafe
16 | import Data.Function
17 |
18 | foreign import data This :: # * -> *
19 |
20 | foreign import data NgReadThis :: !
21 |
22 | foreign import data NgWriteThis :: !
23 |
24 | type ReadEff e a = Eff (ngrthis :: NgReadThis | e) { | a }
25 |
26 | type WriteEff e = Eff (ngwthis :: NgWriteThis | e) Unit
27 |
28 | type ReadWriteEff e r = Eff (ngrthis :: NgReadThis, ngwthis :: NgWriteThis | e) r
29 |
30 | writeThis :: forall e a b. String -> b -> This a -> WriteEff e
31 | writeThis = runFn3 writeThisFn
32 |
33 | extendThis :: forall e a b. { | b } -> This a -> WriteEff e
34 | extendThis = runFn2 extendThisFn
35 |
36 | modifyThis :: forall e a b. ({ | a } -> ReadWriteEff e { | b }) -> This a -> ReadWriteEff e Unit
37 | modifyThis k t = do
38 | t' <- readThis t
39 | w <- unsafeInterleaveEff $ k t'
40 | extendThis w t
41 |
42 | foreign import readThis
43 | " function readThis($this){ \
44 | \ return function(){ \
45 | \ return $this; \
46 | \ } \
47 | \ } " :: forall e a. This a -> ReadEff e a
48 |
49 | foreign import extendThisFn
50 | "function extendThisFn(obj, $this){\
51 | \ return function(){\
52 | \ angular.extend($this, obj);\
53 | \ };\
54 | \}" :: forall e a b. Fn2 { | b } (This a) (WriteEff e)
55 |
56 | foreign import writeThisFn
57 | " function writeThisFn(prop, value, $this){ \
58 | \ return function(){ \
59 | \ $this[prop] = value; \
60 | \ }; \
61 | \ } " :: forall e a b. Fn3 String b (This a) (WriteEff e)
62 |
--------------------------------------------------------------------------------
/src/Angular/Timeout.purs:
--------------------------------------------------------------------------------
1 | module Angular.Timeout
2 | ( Timeout()
3 | , NgTimeout()
4 | , TimeoutEff()
5 | , TimeoutPromise()
6 | , timeout
7 | , timeout'
8 | , timeout''
9 | , timeoutk
10 | , cancel
11 | ) where
12 |
13 | import Control.Monad.Eff
14 | import Control.Monad.Eff.Exception (Error())
15 | import Data.Function
16 | import Data.Maybe
17 |
18 | import Angular.Promise (Promise())
19 |
20 | foreign import data Timeout :: *
21 |
22 | foreign import data NgTimeout :: !
23 |
24 | type TimeoutEff e r = Eff (ngtimeout :: NgTimeout | e) r
25 |
26 | type TimeoutPromise a = Promise Error a
27 |
28 | foreign import timeoutFn
29 | " function timeoutFn(fromMaybe, fn, delay, invokeApply, $timeout){ \
30 | \ return function(){ \
31 | \ return $timeout(fn, fromMaybe(undefined)(delay), fromMaybe(undefined)(invokeApply)); \
32 | \ }; \
33 | \ } "
34 | :: forall e f r. Fn5 (forall a. a -> Maybe a -> a)
35 | (Eff f r)
36 | (Maybe Number)
37 | (Maybe Boolean)
38 | Timeout
39 | (TimeoutEff e (TimeoutPromise r))
40 |
41 | timeout :: forall e f r. Eff f r -> Number -> Boolean -> Timeout -> TimeoutEff e (TimeoutPromise r)
42 | timeout fn delay invoke = runFn5 timeoutFn fromMaybe fn (Just delay) (Just invoke)
43 |
44 | timeout' :: forall e f r. Eff f r -> Number -> Timeout -> TimeoutEff e (TimeoutPromise r)
45 | timeout' fn delay = runFn5 timeoutFn fromMaybe fn (Just delay) Nothing
46 |
47 | timeout'' :: forall e f r. Eff f r -> Timeout -> TimeoutEff e (TimeoutPromise r)
48 | timeout'' fn = runFn5 timeoutFn fromMaybe fn Nothing Nothing
49 |
50 | timeoutk :: forall e f r. Number -> Boolean -> Timeout -> Eff f r -> TimeoutEff e (TimeoutPromise r)
51 | timeoutk delay invoke timeout fn = runFn5 timeoutFn fromMaybe fn (Just delay) (Just invoke) timeout
52 |
53 | foreign import cancelFn
54 | " function cancelFn(fromMaybe, promise, $timeout){ \
55 | \ return function(){ \
56 | \ return $timeout.cancel(fromMaybe(undefined)(promise)); \
57 | \ }; \
58 | \ } "
59 | :: forall e r. Fn3 ((TimeoutPromise r) -> Maybe (TimeoutPromise r) -> (TimeoutPromise r))
60 | (Maybe (TimeoutPromise r))
61 | Timeout
62 | (TimeoutEff e Boolean)
63 |
64 | cancel :: forall e r. TimeoutPromise r -> Timeout -> TimeoutEff e Boolean
65 | cancel promise = runFn3 cancelFn fromMaybe (Just promise)
66 |
--------------------------------------------------------------------------------