Merge branch 'remove-q-lib'
This commit is contained in:
commit
dcd473967b
@ -39,7 +39,7 @@ Compile SCSS to CSS:
|
|||||||
Install JS components:
|
Install JS components:
|
||||||
|
|
||||||
~> cd isso/js
|
~> cd isso/js
|
||||||
~> bower install almond q requirejs requirejs-domready requirejs-text
|
~> bower install almond requirejs requirejs-domready requirejs-text
|
||||||
|
|
||||||
|
|
||||||
Integration
|
Integration
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p><strong>client-side JavaScript</strong></p>
|
<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>
|
done.</p>
|
||||||
<p>Supports Firefox, Safari, Chrome and IE10.</p>
|
<p>Supports Firefox, Safari, Chrome and IE10.</p>
|
||||||
</li>
|
</li>
|
||||||
|
@ -1,41 +1,14 @@
|
|||||||
define(["q"], function(Q) {
|
define(["app/lib/promise"], function(Q) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Q.stopUnhandledRejectionTracking();
|
|
||||||
Q.longStackSupport = true;
|
|
||||||
|
|
||||||
var salt = "Eech7co8Ohloopo9Ol6baimi",
|
var salt = "Eech7co8Ohloopo9Ol6baimi",
|
||||||
location = window.location.pathname;
|
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,
|
var script, endpoint,
|
||||||
js = document.getElementsByTagName("script");
|
js = document.getElementsByTagName("script");
|
||||||
|
|
||||||
|
// prefer `data-isso="//host/api/endpoint"` if provided
|
||||||
for (var i = 0; i < js.length; i++) {
|
for (var i = 0; i < js.length; i++) {
|
||||||
if (js[i].hasAttribute("data-isso")) {
|
if (js[i].hasAttribute("data-isso")) {
|
||||||
endpoint = js[i].getAttribute("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) {
|
if (! endpoint) {
|
||||||
for (i = 0; i < js.length; i++) {
|
for (i = 0; i < js.length; i++) {
|
||||||
if (js[i].getAttribute("async") || js[i].getAttribute("defer")) {
|
if (js[i].getAttribute("async") || js[i].getAttribute("defer")) {
|
||||||
@ -61,24 +35,22 @@ define(["q"], function(Q) {
|
|||||||
endpoint = endpoint.substring(0, endpoint.length - 1);
|
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 xhr = new XMLHttpRequest();
|
||||||
var response = Q.defer();
|
|
||||||
|
|
||||||
function onload() {
|
function onload() {
|
||||||
|
|
||||||
var rule = url.replace(endpoint, "").split("?", 1)[0];
|
|
||||||
var cookie = xhr.getResponseHeader("X-Set-Cookie");
|
var cookie = xhr.getResponseHeader("X-Set-Cookie");
|
||||||
|
|
||||||
if (cookie && cookie.match(/^isso-/)) {
|
if (cookie && cookie.match(/^isso-/)) {
|
||||||
document.cookie = cookie;
|
document.cookie = cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule in rules && rules[rule].indexOf(xhr.status) === -1) {
|
if (xhr.status >= 500) {
|
||||||
response.reject(xhr.responseText);
|
reject(xhr.body);
|
||||||
} else {
|
} 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) {
|
} catch (exception) {
|
||||||
response.reject(exception.message);
|
(reject || console.log)(exception.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.send(data);
|
xhr.send(data);
|
||||||
return response.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var qs = function(params) {
|
var qs = function(params) {
|
||||||
@ -112,70 +83,104 @@ define(["q"], function(Q) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var create = function(tid, data) {
|
var create = function(tid, data) {
|
||||||
return curl("POST", endpoint + "/new?" + qs({uri: tid || location}), JSON.stringify(data)).then(
|
var deferred = Q.defer();
|
||||||
function (rv) { return JSON.parse(rv.body); });
|
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) {
|
var modify = function(id, data) {
|
||||||
return curl("PUT", endpoint + "/id/" + id, JSON.stringify(data)).then(
|
var deferred = Q.defer();
|
||||||
function (rv) { return JSON.parse(rv.body); });
|
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) {
|
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) {
|
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) {
|
var view = function(id, plain) {
|
||||||
return curl("GET", endpoint + "/id/" + id + "?" + qs({plain: plain}), null).then(function (rv) {
|
var deferred = Q.defer();
|
||||||
return JSON.parse(rv.body);
|
curl("GET", endpoint + "/id/" + id + "?" + qs({plain: plain}), null,
|
||||||
});
|
function(rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||||
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
var fetch = function(tid) {
|
var fetch = function(tid) {
|
||||||
|
var deferred = Q.defer();
|
||||||
return curl("GET", endpoint + "/?" + qs({uri: tid || location}), null).then(function (rv) {
|
curl("GET", endpoint + "/?" + qs({uri: tid || location}), null, function(rv) {
|
||||||
if (rv.status === 200) {
|
if (rv.status === 200) {
|
||||||
return JSON.parse(rv.body);
|
deferred.resolve(JSON.parse(rv.body));
|
||||||
|
} else if (rv.status === 404) {
|
||||||
|
deferred.resolve([]);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
deferred.reject(rv.body);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
var count = function(tid) {
|
var count = function(tid) {
|
||||||
return curl("GET", endpoint + "/count?" + qs({uri: tid || location}), null).then(function(rv) {
|
var deferred = Q.defer();
|
||||||
return JSON.parse(rv.body);
|
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) {
|
var like = function(id) {
|
||||||
return curl("POST", endpoint + "/id/" + id + "/like", null).then(function(rv) {
|
var deferred = Q.defer();
|
||||||
return JSON.parse(rv.body);
|
curl("POST", endpoint + "/id/" + id + "/like", null,
|
||||||
});
|
function(rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||||
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
var dislike = function(id) {
|
var dislike = function(id) {
|
||||||
return curl("POST", endpoint + "/id/" + id + "/dislike", null).then(function(rv) {
|
var deferred = Q.defer();
|
||||||
return JSON.parse(rv.body);
|
curl("POST", endpoint + "/id/" + id + "/dislike", null,
|
||||||
});
|
function(rv) { deferred.resolve(JSON.parse(rv.body)); });
|
||||||
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
var remote_addr = function() {
|
var remote_addr = function() {
|
||||||
return curl("GET", endpoint + "/check-ip", null).then(function(rv) {
|
var deferred = Q.defer();
|
||||||
return rv.body;
|
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 {
|
return {
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
salt: salt,
|
salt: salt,
|
||||||
|
|
||||||
remote_addr: remote_addr,
|
remote_addr: remote_addr,
|
||||||
|
|
||||||
create: create,
|
create: create,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Inspired by http://codepen.io/gschier/pen/GLvAy
|
Inspired by http://codepen.io/gschier/pen/GLvAy
|
||||||
*/
|
*/
|
||||||
define(["q"], function(Q) {
|
define(["app/lib/promise"], function(Q) {
|
||||||
|
|
||||||
"use strict";
|
"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
|
* JavaScript implementation of Password-Based Key Derivation Function 2
|
||||||
* (PBKDF2) as defined in RFC 2898.
|
* (PBKDF2) as defined in RFC 2898.
|
||||||
@ -191,11 +191,11 @@ define(["q", "app/lib/sha1"], function(Q, sha1) {
|
|||||||
|
|
||||||
Q.when(text, function(text) {
|
Q.when(text, function(text) {
|
||||||
var pbkdf2 = new PBKDF2(text, salt, iterations, size);
|
var pbkdf2 = new PBKDF2(text, salt, iterations, size);
|
||||||
pbkdf2.deriveKey(function(bla) {}, function(rv) {
|
pbkdf2.deriveKey(function() {}, function(rv) {
|
||||||
deferred.resolve(rv);
|
deferred.resolve(rv);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
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 = {
|
var requirejs = {
|
||||||
paths: {
|
paths: {
|
||||||
q: "components/q/q",
|
|
||||||
text : "components/requirejs-text/text",
|
text : "components/requirejs-text/text",
|
||||||
ready: "components/requirejs-domready/domReady"
|
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(new isso.Postbox(null));
|
||||||
$("#isso-thread").append('<div id="isso-root"></div>');
|
$("#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-num-comments | pluralize : `n` }}", {n: rv.length});
|
||||||
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-no-comments }}");
|
for (var i=0; i < rv.length; i++) {
|
||||||
return;
|
isso.insert(rv[i], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-num-comments | pluralize : `n` }}", {n: rv.length});
|
if (window.location.hash.length > 0) {
|
||||||
for (var i=0; i < rv.length; i++) {
|
$(window.location.hash).scrollIntoView();
|
||||||
isso.insert(rv[i], false);
|
}
|
||||||
|
},
|
||||||
|
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