This repo aims to provide a base for a more modular and better testable Isso client.
!!! BEWARE DRAGONS !!!
$ npm install
$ npm run buildThis will generate embed.dev.js.
Use embed.dev.js in place of the "stock" Isso client JS.
Make demo JS use new client in regular Isso repo:
diff --git a/isso/demo/index.html b/isso/demo/index.html
index 0b043e0..b731dcc 100644
--- a/isso/demo/index.html
+++ b/isso/demo/index.html
@@ -9,8 +9,8 @@
<div id="wrapper" style="max-width: 900px; margin-left: auto; margin-right: auto;">
<h2><a href="index.html">Isso Demo</a></h2>
- <script src="../js/embed.dev.js"
- data-isso="../"
+ <script src="http://localhost:8000/embed.dev.js"
+ data-isso="http://localhost:8080/"
></script>
<!-- Uncomment to only test count functionality: -->
<!-- <script src="../js/count.dev.js"></script> -->Then spin up the server (from regular Isso repo):
$ virtualenv .venv
$ source .venv/bin/activate
(.venv) $ pip install -e .
(.venv) $ isso -c contrib/isso-dev.cfg runFast auto-reloading:
$ npm run watchServe the generated experimental client files at localhost:8000 (from
this experimental client repo:
$ cd dist && python3 -m http.serverBtw, feedback appreciated!
The aim is to modularize the client codebase and make it easier to test, as well as make it a bit more clear to read and to avoid race conditions.
This code makes heavy use of class-like objects. It still only uses ES5 syntax and strict mode. Prototyping and member functions are used heavily. A lot of state is carried and passed. I'm not sure this is the right approach, but it seems to work okay-ish so far.
Example, not sure if this an anti-pattern:
var App = function(conf) {
this.conf = conf;
}
App.prototype.initWidget = function() {
var self = this; // Preserve App object instance context
renderSomething(self.conf);
// [...]
}
// later, in other file:
var app = new app.App('conf');
app.initWidget()I'm still also very unclear about scopes. Especially this and how it resolves
inside Object instances and through calls to prototyped-member functions.
The embed script now exposes the main app object as window.Isso.unstableApp:
window.Isso = {
init: init,
fetchComments: fetchComments,
count: count,
registerExtensions: issoApp.registerExtensions,
// Called "unstable" because app internals are subject to change!
unstableApp: issoApp,
}Called unstableApp because it should not be relied upon, but could still be
nice for testing or (unsafe) extensibility.
To prevent Isso from initializing fully and adding any elements to the page, set
window.Isso.preventInit = true. Then do any setup you require and call
window.Isso.init() and fetchComments() manually.
Now with extensions! See extensions.js and the this.ext attribute of app.
Example:
var AuthExtension = function() {
var addAuthHeader = function(xhr) {
// read auth from somewhere...
var authHeader = ["Auth-Foo", "foo"];
// and add it to every XMLHttpRequest:
xhr.setRequestHeader(authHeader[0], authHeader[1]);
};
this.hooks = {
"api.curl.pre": [addAuthHeader],
};
};
var auth = new AuthExtension();
window.Isso.Ext = {
hooks: auth.hooks,
};
// Register manually:
window.Isso.registerExtensions();Now, every call to api.curl will have the XMLHttpRequest(xhr) object
modified with an added authentication header Auth-Foo = foo.
N.b.: If window.Isso.Ext (with hooks set) is already defined when Isso is
loaded (e.g. in SPAs), Isso will automatically call registerHooks() itself.