Klient og server forventer noget json, men da Django forventer en "csrftoken" skal den hentes fra en cookie og bygges ind i headeren. Jeg har glemt hvor jeg har hentet den cookiereader fra og kan kun undskylde til forfatteren.
#library('remote');
#import('dart:html');
#import('encode-decode.dart');
class Remote{
Cookies _cookies;
Remote(){
_cookies = new Cookies();
}
XMLHttpRequest _buildRequest(String method, String url){
String cookie = _cookies.readCookie('csrftoken');
XMLHttpRequest request = new XMLHttpRequest();
request.withCredentials = true;
request.open(method, url);
if(cookie!=null){
request.setRequestHeader('X-CSRFToken', cookie);
}
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
return request;
}
void _attachEventHandlers(XMLHttpRequest request, void callback(XMLHttpRequest request)){
request.on.abort.add((e){
window.alert(e.toString());
});
request.on.error.add((e){
window.alert(e.toString());
});
request.on.readyStateChange.add((e) {
if (request.readyState == XMLHttpRequest.DONE &&
(request.status == 200 || request.status == 0)) {
callback(request);
}
});
}
void getDocumentData(String path, void callback(XMLHttpRequest request)){
XMLHttpRequest request = _buildRequest('GET', path);
_attachEventHandlers(request, callback);
request.send();
}
void calculateLix(Data data, void callback(XMLHttpRequest request)){
String url = '/editor/find-lix';
runPostJob(url, data, callback);
}
void runPostJob(String url, Data data, void callback(XMLHttpRequest request)){
XMLHttpRequest request = _buildRequest('POST', url);
_attachEventHandlers(request, callback);
var formatedData = data.encoded();
request.send(formatedData);
}
}
class Data{
Data(){
}
static Data create(int documentID, String content, double fraction) {
Data data = new Data();
data.documentID = documentID;
data.content = content;
data.fraction = fraction;
return data;
}
int documentID;
String content;
double fraction;
static String decode(String text){
return decodeURI(text);
}
static String encode(String text){
return encodeURIComponent(text);
}
String _encodedContent(){
return encode(content);
}
String encoded(){
return 'docID=' + documentID + '&content=' + _encodedContent() + '&fraction=' + fraction;
}
String toString(){
return '"documentID": ' + documentID + ', "content": ' + content + ', "fraction": ' + fraction;
}
}
class Cookies {
String readCookie(String name) {
String nameEQ = name + '=';
List<String> ca = document.cookie.split(';');
for (int i = 0; i < ca.length; i++) {
String c = ca[i];
c = c.trim();
if (c.indexOf(nameEQ) == 0) {
return c.substring(nameEQ.length);
}
}
return null;
}
void createCookie(String name, String value, int days) {
String expires;
if (days != null) {
Date now = new Date.now();
Date date = new Date.fromEpoch(now.value + days*24*60*60*1000, new TimeZone.local());
expires = '; expires=' + date.toString();
} else {
Date then = new Date.fromEpoch(0, new TimeZone.utc());
expires = '; expires=' + then.toString();
}
document.cookie = name + '=' + value + expires + '; path=/';
}
void eraseCookie(String name) {
createCookie(name, '', null);
}
}
/*
* Encode/Decode functions for Dart
*
* Copyright 2011 Google Inc.
* Neil Fraser (fraser@google.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#library('encode-decode');
/**
* Implementation of JavaScript's encodeURI function.
* [text] is the string to escape.
* Returns the escaped string.
*/
String encodeURI(text) {
StringBuffer encodedText = new StringBuffer();
final String whiteList = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz' +
'0123456789-_.!~*\'()#;,/?:@&=+\$';
final String hexDigits = '0123456789ABCDEF';
for (int i = 0; i < text.length; i++) {
if (whiteList.indexOf(text[i]) != -1) {
// This character doesn't need encoding.
encodedText.add(text[i]);
continue;
}
int charCode = text.charCodeAt(i);
List<int> byteList = [];
if (charCode < 0x80) {
// One-byte code.
// 0xxxxxxx
byteList.add(charCode);
} else if (charCode < 0x800) {
// Two-byte code.
// 110xxxxx 10xxxxxx
byteList.add(charCode >> 6 | 0xC0);
byteList.add(charCode & 0x3F | 0x80);
} else if (0xD800 <= charCode && charCode < 0xDC00) {
// Low surrogate. Next char must be a high surrogate.
int nextCharCode = text.length == i + 1 ? 0 : text.charCodeAt(i + 1);
if (0xDC00 <= nextCharCode && nextCharCode < 0xE000) {
// Four-byte surrogate pair.
// 11110xxx 10xxxxxx 10xxyyyy 10yyyyyy
// Where xxxxxxxxxxx is offset by 1000000 (0x40)
charCode += 0x40;
byteList.add(charCode >> 8 & 0x7 | 0xF0);
byteList.add(charCode >> 2 & 0x3F | 0x80);
byteList.add(((charCode & 0x3) << 4) |
(nextCharCode >> 6 & 0xF) | 0x80);
byteList.add(nextCharCode & 0x3F | 0x80);
} else {
throw new
IllegalArgumentException('URI malformed: Orphaned low surrogate.');
}
// Skip next character.
i++;
} else if (0xDC00 <= charCode && charCode < 0xE000) {
throw new
IllegalArgumentException('URI malformed: Orphaned high surrogate.');
} else if (charCode < 0x10000) {
// Three-byte code.
// 1110xxxx 10xxxxxx 10xxxxxx
byteList.add(charCode >> 12 | 0xE0);
byteList.add(charCode >> 6 & 0x3F | 0x80);
byteList.add(charCode & 0x3F | 0x80);
}
for (int byteIndex = 0; byteIndex < byteList.length; byteIndex++) {
encodedText.add('%').add(hexDigits[byteList[byteIndex] >> 4])
.add(hexDigits[byteList[byteIndex] & 0xF]);
}
}
return encodedText.toString();
}
/**
* Implementation of JavaScript's encodeURIComponent function.
* [text] is the string to escape.
* Return the escaped string.
*/
String encodeURIComponent(text) {
// This is the same as encodeURI except the following are also escaped:
// #;,/?:@&=+$ -> %23%3B%2C%2F%3F%3A%40%26%3D%2B%24
text = encodeURI(text);
return text.replaceAll('#', '%23')
.replaceAll(';', '%3B')
.replaceAll(',', '%2C')
.replaceAll('/', '%2F')
.replaceAll('?', '%3F')
.replaceAll(':', '%3A')
.replaceAll('@', '%40')
.replaceAll('&', '%26')
.replaceAll('=', '%3D')
.replaceAll('+', '%2B')
.replaceAll('\$', '%24');
}
/**
* Implementation of JavaScript's decodeURI function.
* [text] is the string to unescape.
* Returns the unescaped string.
*/
String decodeURI(text) {
final String hexDigits = '0123456789ABCDEF';
// First, break up the text into parts.
List<String> parts = text.split('%');
int state = 0;
int multiByte; // Temp register for assembling a multi-byte value.
bool surrogate = false;
// Skip the first element, it's guaranteed to be a (possibly empty) string.
for (int i = 1; i < parts.length; i++) {
String part = parts[i];
if (part.length < 2) {
throw new IllegalArgumentException('URI malformed: Missing digits.');
}
int hex1 = hexDigits.indexOf(part[0].toUpperCase());
int hex2 = hexDigits.indexOf(part[1].toUpperCase());
parts[i] = part.substring(2);
if (hex1 == -1 || hex2 == -1) {
throw new IllegalArgumentException('URI malformed: Invalid digits.');
}
int charCode = hex1 * 16 + hex2;
if (state == 0) {
if (charCode < 0x80) {
// One-byte code.
// 0xxxxxxx
multiByte = charCode;
state = 0;
} else if ((charCode & 0xE0) == 0xC0) {
// Two-byte code.
// 110xxxxx 10xxxxxx
multiByte = charCode & 0x1F;
state = 1;
} else if ((charCode & 0xF0) == 0xE0) {
// Three-byte code.
// 1110xxxx 10xxxxxx 10xxxxxx
multiByte = charCode & 0xF;
state = 2;
} else if ((charCode & 0xF8) == 0xF0) {
// Four-byte surrogate pair.
// 11110xxx 10xxxxxx 10xxyyyy 10yyyyyy
multiByte = charCode & 0x7;
state = 3;
surrogate = true;
} else {
throw new IllegalArgumentException('URI malformed: Unknown Unicode.');
}
} else {
// All continuation bytes are in the form 10xxxxxx.
if ((charCode & 0xC0) != 0x80) {
throw new IllegalArgumentException('URI malformed: Expect 10xxxxxx.');
}
multiByte = (multiByte << 6) | (charCode & 0x3F);
state--;
}
if (state == 0) {
// Character is fully assembled. Add to string.
if (surrogate) {
surrogate = false;
// Insert surrogate pair.
// xxxxxxxxxxxyyyyyyyyyy (21 bits)
// Where xxxxxxxxxxx is offset by 1000000 (0x40)
int x = (multiByte >> 10) - 0x40 + 0xD800;
int y = (multiByte & 0x3FF) + 0xDC00;
if (x >= 0xDC00 || y >= 0xE000) {
throw new
IllegalArgumentException('URI malformed: Invalid surrogate.');
}
parts.insertRange(i, 1, new String.fromCharCodes([x, y]));
} else {
// Insert a single character.
parts.insertRange(i, 1, new String.fromCharCodes([multiByte]));
}
// Skip the element we just inserted.
i++;
} else {
// This code must be directly followed by another code.
if (!parts[i].isEmpty()) {
throw new IllegalArgumentException('URI malformed: Incomplete code.');
}
}
}
if (state != 0) {
throw new IllegalArgumentException('URI malformed: Truncated code.');
}
return Strings.join(parts, '');
}
/**
* Implementation of JavaScript's decodeURIComponent function.
* [text] is the string to unescape.
* Returns the unescaped string.
*/
String decodeURIComponent(text) {
return decodeURI(text);
}