More reorganization and initial form interception implementation

feature/core
Sven Slootweg 7 years ago
parent cd0238c86b
commit 48073c0a0c

@ -2,9 +2,9 @@ app
window(each="{windowItem in windows}", router="{parent.router}", window-title="{windowItem.title}", width=640, height=480, x="{windowItem.x}", y="{windowItem.y}", z=0, resizable="true", url="{windowItem.url}")
script.
const stateRouter = require("../../lib/frontend/riot-state-router");
const stateRouter = require("../../lib/riot/state-router");
this.mixin(require("../../lib/frontend/riot-on-child"));
this.mixin(require("../../lib/riot/mixins/on-child"));
this.mixin(require("riot-query").mixin);
this.windows = [

@ -39,3 +39,14 @@ view-manager
["get", "post", "put", "delete", "patch", "head"].forEach((method) => {
this[method] = this.navigate.bind(this, method);
});
// FIXME: Get rid of jQuery here?
$(this.root).on("submit", "form:not(.no-intercept)", (event) => {
Promise.try(() => {
let form = event.target;
event.preventDefault();
event.stopPropagation();
return this.navigate(form.method, form.action, new FormData(form));
});
});

@ -18,7 +18,7 @@ window
require("../../lib/jquery/draggable")($);
this.mixin(query.mixin);
this.mixin(require("../../lib/frontend/riot-change"));
this.mixin(require("../../lib/riot/mixins/change"));
Object.assign(this, {
dragged: false,

@ -0,0 +1,30 @@
'use strict';
const qs = require("qs");
module.exports = function formDataToObject(formData) {
let items = Array.from(formData.entries()).reduce((items, [key, value]) => {
if (key.match(/\[\]$/)) {
/* Array item */
if (items[key] == null) {
items[key] = [];
}
items[key].push(value);
} else {
/* Single item */
items[key] = value;
}
return items;
}, {});
console.log("ITEMS", qs.stringify(items));
/* This is a bit of a hack... we have an array of values that may or may not
involve array and object specifications, and the `items` object is an
object that contains a flat set of them as keys and values. By passing it
into `stringify` and `parse` consecutively, we get back a properly nested
version of it. */
return qs.parse(qs.stringify(items));
};

@ -3,6 +3,9 @@ const pathToRegexp = require("path-to-regexp");
const url = require("url");
const xtend = require("xtend");
const defaultValue = require("default-value");
const objectToFormData = require("object-to-formdata");
const formDataToObject = require("../formdata-to-object");
module.exports = function() {
let routes = [];
@ -37,26 +40,57 @@ module.exports = function() {
function handle(method, uri, data) {
return Promise.try(() => {
// FIXME: Support relative paths?
let {path, query} = url.parse(uri, true);
let route = getRoute(method, path);
let tasks = [];
let body;
if (data instanceof FormData) {
body = formDataToObject(data);
} else {
body = data;
}
let req = {
path: path,
query: query,
body: data,
params: route.params,
pass: function(options = {}) {
return Promise.try(() => {
return window.fetch(uri, Object.assign({
method: method,
credentials: true,
body: objectToFormData(this.body)
}, options));
}).then((response) => {
if (!response.ok) {
// FIXME: Is this what we want?
throw new Error(`Got a non-200 response: ${response.status}`, {response: response});
} else {
return Promise.try(() => {
return response.json();
}).then((json) => {
return {
status: response.status,
body: json
}
});
}
});
// FIXME: window.fetch passthrough
},
passRender: function(viewName, options = {}) {
return Promise.try(() => {
return this.pass(options);
return this.pass(options.requestOptions);
}).then((response) => {
let locals = defaultValue(options.locals, {});
let combinedLocals = xtend(locals, response.body);
res.render(viewName, combinedLocals, options);
res.render(viewName, combinedLocals, options.renderOptions);
});
}
}
@ -117,4 +151,4 @@ module.exports = function() {
}
return api;
}
}

@ -18,7 +18,9 @@
"express-promise-router": "^1.0.0",
"in-array": "^0.1.2",
"jquery": "^3.2.1",
"object-to-formdata": "^1.0.9",
"pug": "^2.0.0-beta11",
"qs": "^6.4.0",
"rfr": "^1.2.3",
"riot": "^3.4.2",
"riot-query": "^1.0.0",

Loading…
Cancel
Save