-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathdart_jsonp.dart
More file actions
107 lines (86 loc) · 3.38 KB
/
dart_jsonp.dart
File metadata and controls
107 lines (86 loc) · 3.38 KB
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
104
105
106
107
library dart_jsonp;
import 'dart:html';
import 'dart:json';
import 'dart:async';
typedef void OnDataHandler(Map jsonObject);
/// Allow jsonp data access without the fuss by injecting and removing
/// a javascript callback function and a dart postmessage handler function
class JsonpCallback {
String _callbackFunctionName;
String get callbackFunctionName => _callbackFunctionName;
ScriptElement _script;
var _onMessage;
var _onMessageSub;
/// constructor - the [_callbackFunctionName] is mandatory.
/// This is the name that you will provide to your json request url
/// and it will be injected into the dom as a javscript callback function
/// once the callback is received, the function will be removed.
///
/// IMPORTANT: Make sure that you don't have two callback functions
/// with the same name.
JsonpCallback(String this._callbackFunctionName) {
_script = new Element.tag("script");
}
/// add the callback script and wrap it in the callback function name
/// so that we can identify it when dart receives the postmessage.
/// We want to make sure that the postMessage is for the correct
/// call
_addScriptText() {
_script.text = """
function $_callbackFunctionName(s) {
var messageData = JSON.stringify(s);
var data = '{"requestName":"$_callbackFunctionName","jsonpData":' + messageData + '}';
window.postMessage(data, '*');
}
""";
}
/// set the script to be empty, as we can't actually remove tags
/// from the dom yet
_removeScriptText() {
_script.text = "";
_script.remove();
}
/// Performs JSON request to the [url].
/// The url must contain the callback function name that was
/// passed in on the constructor
// eg: http://example.com/query?callback=myJsCallback
Future<Map> doCallback(String url, [OnDataHandler onData]) {
if (url.contains(this._callbackFunctionName) == false) {
throw "callback url must contain the callback function name!";
}
if (onData != null) {
this.onDataReceived = onData;
}
var completer = new Completer<Map>();
_onMessage = (MessageEvent event) {
String s = event.data;
Map json = parse(s);
if (json["requestName"] == _callbackFunctionName) {
// if this is the correct handler, then remove the handler and
// call the onDataReceived callback and return a future
_onMessageSub.cancel();
_removeScriptText();
Map result = json["jsonpData"];
// if we have a callback handler, then use it
if (onDataReceived != null) {
onDataReceived(result);
}
// also return a future
completer.complete(result);
}
};
//add the dart onMessage handler
_onMessageSub = window.onMessage.listen(_onMessage);
//add the correct text back into the JavaScript handler
_addScriptText();
document.body.nodes.add(_script); //add the jsonp callback javascript
//create the script that will invoke the JSON call
ScriptElement script = new Element.tag("script");
script.src = url;
// add and remove it is enough
document.body.nodes.add(script);
document.body.nodes.removeLast(); //remove the script which initiates the call
return completer.future;
}
OnDataHandler onDataReceived;
}