-
Notifications
You must be signed in to change notification settings - Fork 2
/
angular-elm.js
103 lines (95 loc) · 3.5 KB
/
angular-elm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
(function (ng, Elm) {
/**
* Usage:
*
* For fullscreen mode
* <body elm module="ModuleName">
*
* For embedded mode
* <div elm module="ModuleName">
*
* For worker mode
* <elm module="ModuleName">
*
* ----
*
* Flags (for Html.App.programWithFlags):
* <div elm module="ModuleName" flags='{myValue: "Hello init!"}'>
*
* ----
*
* Ports prefix ("namespacing"):
* <div elm module="ModuleName" ports="prefix">
* Then instead of $scope.myPort you use $scope.prefix.myPort .
*
* ----
*
* Ports usage:
*
* Sending from JS: (if you have Elm port 'fromJsToElm')
* $scope.fromJsToElm = 'This gets automatically sent to Elm!';
*
* Subscribing: (if you have Elm port 'fromElmToJs')
* $scope.fromElmToJs = function (msg) {
* console.log(msg);
* }
*/
ng.module('Elm', [])
.directive('elm', function ($parse, $timeout) {
function link(scope, element, attrs) {
var target = element[0];
var flags = $parse(attrs.flags)(scope);
var ports = attrs.ports;
var moduleParts = attrs.module.split('.');
var module = Elm;
var elm;
while (moduleParts[0]) {
module = module[moduleParts.shift()];
}
if (target.nodeName === 'BODY') {
// <body elm module="" ...></body>
elm = module.fullscreen(flags)
} else if (target.nodeName === 'ELM') {
// <elm module="" ...></elm>
elm = module.worker(flags);
} else if (target.nodeName === 'DIV') {
// <div elm module="" ...></div>
elm = module.embed(target, flags);
}
if (elm) {
var portsPrefix = ports ? ports + '.' : '';
ng.forEach (elm.ports, function(port, name) {
if (port.send) {
scope.$watch(portsPrefix + name, function(value) {
try {
port.send(value);
} catch (ex) {
// elm border check error
}
});
} else if (port.subscribe) {
var adapterFn;
scope.$watch(portsPrefix + name, function(newFn) {
if (adapterFn) {
port.unsubscribe(adapterFn);
adapterFn = undefined;
}
if (ng.isFunction(newFn)) {
adapterFn = function (value) {
$timeout(function () {
newFn(value);
});
};
port.subscribe(adapterFn);
}
});
}
});
}
}
return {
restrict: 'EA',
link: link
};
});
})(angular, Elm);