Merge branch 'remove-q-lib'
This commit is contained in:
commit
dcd473967b
@ -39,7 +39,7 @@ Compile SCSS to CSS:
|
||||
Install JS components:
|
||||
|
||||
~> cd isso/js
|
||||
~> bower install almond q requirejs requirejs-domready requirejs-text
|
||||
~> bower install almond requirejs requirejs-domready requirejs-text
|
||||
|
||||
|
||||
Integration
|
||||
|
@ -30,7 +30,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>client-side JavaScript</strong></p>
|
||||
<p>Embed a single JS file, 54kb (18kb gzipped) and you are
|
||||
<p>Embed a single JS file, 52kb (16kb gzipped) and you are
|
||||
done.</p>
|
||||
<p>Supports Firefox, Safari, Chrome and IE10.</p>
|
||||
</li>
|
||||
|
@ -1,41 +1,14 @@
|
||||
define(["q"], function(Q) {
|
||||
define(["app/lib/promise"], function(Q) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Q.stopUnhandledRejectionTracking();
|
||||
Q.longStackSupport = true;
|
||||
|
||||
var salt = "Eech7co8Ohloopo9Ol6baimi",
|
||||
location = window.location.pathname;
|
||||
|
||||
var rules = {
|
||||
"/": [200, 404],
|
||||
"/new": [201, 202],
|
||||
"/id/\\d+": [200, 403, 404],
|
||||
"/id/\\d+/(like/dislike)": [200],
|
||||
"/count": [200]
|
||||
};
|
||||
|
||||
/*
|
||||
* Detect Isso API endpoint. There are typically two use cases:
|
||||
*
|
||||
* 1. use minified, single-file JavaScript. The browser interprets
|
||||
* scripts sequentially, thus we can safely use the last script
|
||||
* tag. Then, we chop off some characters -- /js/embed.min.s --
|
||||
* and we're done.
|
||||
*
|
||||
* If the script is not served by Isso directly, a custom data
|
||||
* attribute can be used to override the default detection
|
||||
* mechanism:
|
||||
*
|
||||
* .. code-block:: html
|
||||
*
|
||||
* <script data-isso="http://example.tld/path/" src="/.../embed.min.js"></script>
|
||||
*/
|
||||
|
||||
var script, endpoint,
|
||||
js = document.getElementsByTagName("script");
|
||||
|
||||
// prefer `data-isso="//host/api/endpoint"` if provided
|
||||
for (var i = 0; i < js.length; i++) {
|
||||
if (js[i].hasAttribute("data-isso")) {
|
||||
endpoint = js[i].getAttribute("data-isso");
|
||||
@ -43,6 +16,7 @@ define(["q"], function(Q) {
|
||||
}
|
||||
}
|
||||
|
||||
// if no async-script is embedded, use the last script tag of `js`
|
||||
if (! endpoint) {
|
||||
for (i = 0; i < js.length; i++) {
|
||||
if (js[i].getAttribute("async") || js[i].getAttribute("defer")) {
|
||||
@ -61,24 +35,22 @@ define(["q"], function(Q) {
|
||||
endpoint = endpoint.substring(0, endpoint.length - 1);
|
||||
}
|
||||
|
||||
var curl = function(method, url, data) {
|
||||
var curl = function(method, url, data, resolve, reject) {
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
var response = Q.defer();
|
||||
|
||||
function onload() {
|
||||
|
||||
var rule = url.replace(endpoint, "").split("?", 1)[0];
|
||||
var cookie = xhr.getResponseHeader("X-Set-Cookie");
|
||||
|
||||
if (cookie && cookie.match(/^isso-/)) {
|
||||
document.cookie = cookie;
|
||||
}
|
||||
|
||||
if (rule in rules && rules[rule].indexOf(xhr.status) === -1) {
|
||||
response.reject(xhr.responseText);
|
||||
if (xhr.status >= 500) {
|
||||
reject(xhr.body);
|
||||
} else {
|
||||
response.resolve({status: xhr.status, body: xhr.responseText});
|
||||
resolve({status: xhr.status, body: xhr.responseText});
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,11 +65,10 @@ define(["q"], function(Q) {
|
||||
}
|
||||
};
|
||||
} catch (exception) {
|
||||
response.reject(exception.message);
|
||||
(reject || console.log)(exception.message);
|
||||
}
|
||||
|
||||
xhr.send(data);
|
||||
return response.promise;
|
||||
};
|
||||
|
||||
var qs = function(params) {
|
||||
@ -112,70 +83,104 @@ define(["q"], function(Q) {
|
||||
};
|
||||
|
||||
var create = function(tid, data) {
|
||||
return curl("POST", endpoint + "/new?" + qs({uri: tid || location}), JSON.stringify(data)).then(
|
||||
function (rv) { return JSON.parse(rv.body); });
|
||||
var deferred = Q.defer();
|
||||
curl("POST", endpoint + "/new?" + qs({uri: tid || location}), JSON.stringify(data),
|
||||
function (rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var modify = function(id, data) {
|
||||
return curl("PUT", endpoint + "/id/" + id, JSON.stringify(data)).then(
|
||||
function (rv) { return JSON.parse(rv.body); });
|
||||
var deferred = Q.defer();
|
||||
curl("PUT", endpoint + "/id/" + id, JSON.stringify(data), function (rv) {
|
||||
if (rv.status === 403) {
|
||||
deferred.reject("Not authorized to modify this comment!");
|
||||
} else if (rv.status === 200) {
|
||||
deferred.resolve(JSON.parse(rv.body));
|
||||
} else {
|
||||
deferred.reject(rv.body);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var remove = function(id) {
|
||||
return curl("DELETE", endpoint + "/id/" + id, null).then(function(rv) {
|
||||
var deferred = Q.defer();
|
||||
curl("DELETE", endpoint + "/id/" + id, null, function(rv) {
|
||||
if (rv.status === 403) {
|
||||
throw "Not authorized to remove this comment!";
|
||||
deferred.reject("Not authorized to remove this comment!");
|
||||
} else if (rv.status === 200) {
|
||||
deferred.resolve(JSON.parse(rv.body) === null);
|
||||
} else {
|
||||
deferred.reject(rv.body);
|
||||
}
|
||||
|
||||
return JSON.parse(rv.body) === null;
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var view = function(id, plain) {
|
||||
return curl("GET", endpoint + "/id/" + id + "?" + qs({plain: plain}), null).then(function (rv) {
|
||||
return JSON.parse(rv.body);
|
||||
});
|
||||
var deferred = Q.defer();
|
||||
curl("GET", endpoint + "/id/" + id + "?" + qs({plain: plain}), null,
|
||||
function(rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var fetch = function(tid) {
|
||||
|
||||
return curl("GET", endpoint + "/?" + qs({uri: tid || location}), null).then(function (rv) {
|
||||
var deferred = Q.defer();
|
||||
curl("GET", endpoint + "/?" + qs({uri: tid || location}), null, function(rv) {
|
||||
if (rv.status === 200) {
|
||||
return JSON.parse(rv.body);
|
||||
deferred.resolve(JSON.parse(rv.body));
|
||||
} else if (rv.status === 404) {
|
||||
deferred.resolve([]);
|
||||
} else {
|
||||
return [];
|
||||
deferred.reject(rv.body);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var count = function(tid) {
|
||||
return curl("GET", endpoint + "/count?" + qs({uri: tid || location}), null).then(function(rv) {
|
||||
return JSON.parse(rv.body);
|
||||
var deferred = Q.defer();
|
||||
curl("GET", endpoint + "/count?" + qs({uri: tid || location}), null, function(rv) {
|
||||
if (rv.status === 200) {
|
||||
deferred.resolve(JSON.parse(rv.body));
|
||||
} else if (rv.status === 404) {
|
||||
deferred.resolve(0);
|
||||
} else {
|
||||
deferred.reject(rv.body);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var like = function(id) {
|
||||
return curl("POST", endpoint + "/id/" + id + "/like", null).then(function(rv) {
|
||||
return JSON.parse(rv.body);
|
||||
});
|
||||
var deferred = Q.defer();
|
||||
curl("POST", endpoint + "/id/" + id + "/like", null,
|
||||
function(rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var dislike = function(id) {
|
||||
return curl("POST", endpoint + "/id/" + id + "/dislike", null).then(function(rv) {
|
||||
return JSON.parse(rv.body);
|
||||
});
|
||||
var deferred = Q.defer();
|
||||
curl("POST", endpoint + "/id/" + id + "/dislike", null,
|
||||
function(rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var remote_addr = function() {
|
||||
return curl("GET", endpoint + "/check-ip", null).then(function(rv) {
|
||||
return rv.body;
|
||||
var deferred = Q.defer();
|
||||
curl("GET", endpoint + "/check-ip", null, function(rv) {
|
||||
if (rv.status === 200) {
|
||||
deferred.resolve(rv.body);
|
||||
} else {
|
||||
deferred.reject(rv.body);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return {
|
||||
endpoint: endpoint,
|
||||
salt: salt,
|
||||
|
||||
remote_addr: remote_addr,
|
||||
|
||||
create: create,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Inspired by http://codepen.io/gschier/pen/GLvAy
|
||||
*/
|
||||
define(["q"], function(Q) {
|
||||
define(["app/lib/promise"], function(Q) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
define(["q", "app/lib/sha1"], function(Q, sha1) {
|
||||
define(["app/lib/promise", "app/lib/sha1"], function(Q, sha1) {
|
||||
/*
|
||||
* JavaScript implementation of Password-Based Key Derivation Function 2
|
||||
* (PBKDF2) as defined in RFC 2898.
|
||||
@ -191,10 +191,10 @@ define(["q", "app/lib/sha1"], function(Q, sha1) {
|
||||
|
||||
Q.when(text, function(text) {
|
||||
var pbkdf2 = new PBKDF2(text, salt, iterations, size);
|
||||
pbkdf2.deriveKey(function(bla) {}, function(rv) {
|
||||
pbkdf2.deriveKey(function() {}, function(rv) {
|
||||
deferred.resolve(rv);
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
57
isso/js/app/lib/promise.js
Normal file
57
isso/js/app/lib/promise.js
Normal file
@ -0,0 +1,57 @@
|
||||
define(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var stderr = function(text) { console.log(text); };
|
||||
|
||||
var Promise = function() {
|
||||
this.success = [];
|
||||
this.errors = [];
|
||||
};
|
||||
|
||||
Promise.prototype.then = function(onSuccess, onError) {
|
||||
this.success.push(onSuccess);
|
||||
if (onError) {
|
||||
this.errors.push(onError);
|
||||
} else {
|
||||
this.errors.push(stderr);
|
||||
}
|
||||
};
|
||||
|
||||
var defer = function() {
|
||||
this.promise = new Promise();
|
||||
};
|
||||
|
||||
defer.prototype = {
|
||||
promise: Promise,
|
||||
resolve: function(rv) {
|
||||
this.promise.success.forEach(function(callback) {
|
||||
window.setTimeout(function() {
|
||||
callback(rv);
|
||||
}, 0);
|
||||
});
|
||||
},
|
||||
|
||||
reject: function(error) {
|
||||
this.promise.errors.forEach(function(callback) {
|
||||
window.setTimeout(function() {
|
||||
callback(error);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var when = function(obj, func) {
|
||||
if (obj instanceof Promise) {
|
||||
return obj.then(func);
|
||||
} else {
|
||||
return func(obj);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
defer: function() { return new defer(); },
|
||||
when: when
|
||||
};
|
||||
|
||||
});
|
@ -1,6 +1,5 @@
|
||||
var requirejs = {
|
||||
paths: {
|
||||
q: "components/q/q",
|
||||
text : "components/requirejs-text/text",
|
||||
ready: "components/requirejs-domready/domReady"
|
||||
},
|
||||
|
@ -26,23 +26,25 @@ require(["ready", "app/config", "app/api", "app/isso", "app/count", "app/dom", "
|
||||
$("#isso-thread").append(new isso.Postbox(null));
|
||||
$("#isso-thread").append('<div id="isso-root"></div>');
|
||||
|
||||
api.fetch($("#isso-thread").getAttribute("data-isso-id")).then(function(rv) {
|
||||
api.fetch($("#isso-thread").getAttribute("data-isso-id")).then(
|
||||
function(rv) {
|
||||
if (! rv.length) {
|
||||
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-no-comments }}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (! rv.length) {
|
||||
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-no-comments }}");
|
||||
return;
|
||||
}
|
||||
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-num-comments | pluralize : `n` }}", {n: rv.length});
|
||||
for (var i=0; i < rv.length; i++) {
|
||||
isso.insert(rv[i], false);
|
||||
}
|
||||
|
||||
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-num-comments | pluralize : `n` }}", {n: rv.length});
|
||||
for (var i=0; i < rv.length; i++) {
|
||||
isso.insert(rv[i], false);
|
||||
if (window.location.hash.length > 0) {
|
||||
$(window.location.hash).scrollIntoView();
|
||||
}
|
||||
},
|
||||
function(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}).fail(function(err) {
|
||||
console.log(err);
|
||||
}).done(function() {
|
||||
if (window.location.hash.length > 0) {
|
||||
$(window.location.hash).scrollIntoView();
|
||||
}
|
||||
});
|
||||
);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user