Skip to content

Commit

Permalink
e-json as a template
Browse files Browse the repository at this point in the history
  • Loading branch information
Guseyn committed Dec 12, 2019
1 parent 90092b2 commit 5fb5a93
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 126 deletions.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [Simple E-JSON](#simple-e-json)
- [E-JSON with progress bar](#e-json-with-progress-bar)
- [E-JSON with mapped error](#e-json-with-mapped-error)
- [E-JSON as template](#e-json-as-template)
- [Simple E-FOR-EACH](#simple-e-for-each)
- [Simple E-IF](#simple-e-if)
- [Simple E-FORM](#simple-e-form)
Expand Down Expand Up @@ -184,10 +185,49 @@ Thanks to HTML5 it's possible for relevant browsers. Read further and you'll see

If you need some request headers, you can specify them in the attribute `data-request-headers` with format `{ "headerName": "headerValue", ... }`.

You can also add attributes `data-ajax-icon` and `data-progress-bar` as element selectors for presenting progress of fetching data from the server. You can see how to use them in the [examples](#simple-e-html-page).
You can also add attributes `data-ajax-icon` and `data-progress-bar` as element selectors for presenting progress of fetching data from the server. You can see how to use them in the [examples](#simple-e-json).

</details>

<details>
<summary><b>E-JSON template</b></summary><br>

You can use `e-json` as a `<template>` element, if you just need to map response.

```json
title = 'Humbug'
{
"title": "Humbug",
"artist": "Arctic Monkeys",
"type": "studio album",
"releaseDate": "19 August 2009",
"genre": "psychedelic rock, hard rock, stoner rock, desert rock",
"length": "39:20",
"label": "Domino",
"producer": "James Ford, Joshua Homme"
}
```

Then you can fetch it via `e-json` like in following html code:

```html
<template is="e-json" data-src="/../album/Humbug" data-object-name="albumResponse">
<div data-text="Title: ${albumResponse.body.title}"></div>
<div data-text="Artist: ${albumResponse.body.artist}"></div>
<div data-text="Type: ${albumResponse.body.type}"></div>
<div data-text="Release date: ${albumResponse.body.releaseDate}"></div>
<div data-text="Genre: ${albumResponse.body.genre}"></div>
<div data-text="Length: ${albumResponse.body.length}"></div>
<div data-text="Label: ${albumResponse.body.label}"></div>
<div data-text="Producer: ${albumResponse.body.producer}"></div>
</template>
```

Here you don't use `data-response-name` attribute as you don't need apply actions on response via `data-actions-on-response` attribute. But you still have to specify `data-object-name` to define a variable for the response, so you can use it as a mapping object inside of `e-json` template.

And as for simple `e-json` you can also add attributes `data-ajax-icon` and `data-progress-bar` as element selectors for presenting progress of fetching data from the server. You can see how to use them in the [examples](#e-json-as-template).
</details>

<details>
<summary><b>E-FOR-EACH template</b></summary><br>

Expand Down
313 changes: 199 additions & 114 deletions ehtml.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ehtml.bundle.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/backend/static/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<a href="/../simple-ejson-page.html">Simple E-JSON</a>
<a href="/../e-json-with-progress.html">E-JSON with progress bar</a>
<a href="/../e-json-with-mapped-error-message.html">E-JSON with mapped error</a>
<a href="/../e-json-template.html">E-JSON template</a>
<a href="/../simple-e-for-each.html">Simple E-FOR-EACH</a>
<a href="/../simple-e-if.html">Simple E-IF</a>
<a href="/../simple-e-form.html">Simple E-FORM</a>
Expand Down
2 changes: 1 addition & 1 deletion examples/backend/static/js/ehtml.bundle.min.js

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions examples/src/e-json-template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<!-- http://localhost:8000/simple-ejson-page.html -->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">

<head>
<title>simple e-json page</title>
<link rel="shortcut icon" href="/../images/favicon.ico"/>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/../css/normalize.css">
<link rel="stylesheet" href="/../css/main.css">
<script src="/../js/ehtml.bundle.min.js" type="text/javascript"></script>
</head>

<body class="main">
<div class="base">
<div class="profile-box">
<img class="ajax-icon" id="ajax-icon" src="/../images/ajax-icon.svg"/>
<template
is="e-json"
data-src="/../profile?name=Amanda"
data-ajax-icon="#ajax-icon"
data-object-name="profileResponse"
>
<img class="photo" src="${profileResponse.body.photo}"/>
<div class="user-info">
<div class="name" data-text="${profileResponse.body.name}"></div>
<div class="email" data-text="${profileResponse.body.email}"></div>
<div class="other-details">
<div data-text="Age: ${profileResponse.body.age}"></div>
<div data-text="Country: ${profileResponse.body.country}"></div>
<div data-text="Profession: ${profileResponse.body.profession}"></div>
</div>
</div>
</template>
</div>
</div>
</body>

</html>
75 changes: 75 additions & 0 deletions out/E/E_JSON_TEMPLATE.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

var E = require('./E');

var _require = require('./../cutie/exports'),
as = _require.as;

var _require2 = require('./../async-dom/exports'),
FirstParsedElmSelector = _require2.FirstParsedElmSelector,
PreparedProgressBar = _require2.PreparedProgressBar,
ShownElement = _require2.ShownElement,
HiddenElement = _require2.HiddenElement;

var _require3 = require('./../async-ajax/exports'),
ResponseFromAjaxRequest = _require3.ResponseFromAjaxRequest,
ResponseBody = _require3.ResponseBody,
ResponseHeaders = _require3.ResponseHeaders,
ResponseStatusCode = _require3.ResponseStatusCode,
JSResponseByHTTPReponseComponents = _require3.JSResponseByHTTPReponseComponents;

var _require4 = require('./../async-object/exports'),
CreatedOptions = _require4.CreatedOptions;

var _require5 = require('./../async-json/exports'),
ParsedJSON = _require5.ParsedJSON;

var _require6 = require('./../async-string/exports'),
StringFromBuffer = _require6.StringFromBuffer;

var _require7 = require('./../events/exports'),
ShowProgressEvent = _require7.ShowProgressEvent;

var _require8 = require('./../async-dom/exports'),
ElementWithMappedObject = _require8.ElementWithMappedObject;

var E_JSON_TEMPLATE =
/*#__PURE__*/
function (_E) {
_inherits(E_JSON_TEMPLATE, _E);

function E_JSON_TEMPLATE(node) {
_classCallCheck(this, E_JSON_TEMPLATE);

return _possibleConstructorReturn(this, _getPrototypeOf(E_JSON_TEMPLATE).call(this, node));
}

_createClass(E_JSON_TEMPLATE, [{
key: "activate",
value: function activate() {
new ShownElement(new FirstParsedElmSelector(this.node.getAttribute('data-ajax-icon')).as('AJAX_ICON')).after(new PreparedProgressBar(new FirstParsedElmSelector(this.node.getAttribute('data-progress-bar'))).as('PROGRESS_BAR').after(new ResponseFromAjaxRequest(new CreatedOptions('url', this.node.getAttribute('data-src'), 'method', 'GET', 'headers', new ParsedJSON(this.node.getAttribute('data-request-headers') || '{}'), 'progressEvent', new ShowProgressEvent(as('PROGRESS_BAR')))).as('RESPONSE').after(new HiddenElement(as('AJAX_ICON')).after(new ElementWithMappedObject(this.node, new JSResponseByHTTPReponseComponents(new ParsedJSON(new StringFromBuffer(new ResponseBody(as('RESPONSE')))), new ResponseHeaders(as('RESPONSE')), new ResponseStatusCode(as('RESPONSE')))))))).call();
}
}]);

return E_JSON_TEMPLATE;
}(E);

module.exports = E_JSON_TEMPLATE;
1 change: 1 addition & 0 deletions out/E/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module.exports = {
'e-html': require('./E_HTML'),
'e-json': require('./E_JSON'),
'e-json-template': require('./E_JSON_TEMPLATE'),
'e-if': require('./E_IF'),
'e-for-each': require('./E_FOR_EACH'),
'e-form': require('./E_FORM'),
Expand Down
17 changes: 12 additions & 5 deletions out/MutationObservation.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,23 +128,30 @@ function () {
}, {
key: "nodeName",
value: function nodeName(node) {
if (this.isTemplateWithType(node, 'e-page-with-url')) {
if (this.isTemplateWithType(node, 'e-json')) {
return 'e-json-template';
} else if (this.isTemplateWithTypeExclusively(node, 'e-page-with-url')) {
return 'e-page-with-url';
} else if (this.isTemplateWithType(node, 'e-if')) {
} else if (this.isTemplateWithTypeExclusively(node, 'e-if')) {
return 'e-if';
} else if (this.isTemplateWithType(node, 'e-for-each')) {
} else if (this.isTemplateWithTypeExclusively(node, 'e-for-each')) {
return 'e-for-each';
}

return node.nodeName.toLowerCase();
}
}, {
key: "isTemplateWithType",
value: function isTemplateWithType(node, type) {
key: "isTemplateWithTypeExclusively",
value: function isTemplateWithTypeExclusively(node, type) {
if (node.nodeName.toLowerCase() === type) {
throw new Error("".concat(type, " must be <template>"));
}

return this.isTemplateWithType(node, type);
}
}, {
key: "isTemplateWithType",
value: function isTemplateWithType(node, type) {
if (this.isTemplate(node)) {
var templateType = node.getAttribute('is');

Expand Down
69 changes: 69 additions & 0 deletions src/E/E_JSON_TEMPLATE.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict'

const E = require('./E')
const { as } = require('./../cutie/exports')
const { FirstParsedElmSelector, PreparedProgressBar, ShownElement, HiddenElement } = require('./../async-dom/exports')
const { ResponseFromAjaxRequest, ResponseBody, ResponseHeaders, ResponseStatusCode, JSResponseByHTTPReponseComponents } = require('./../async-ajax/exports')
const { CreatedOptions } = require('./../async-object/exports')
const { ParsedJSON } = require('./../async-json/exports')
const { StringFromBuffer } = require('./../async-string/exports')
const { ShowProgressEvent } = require('./../events/exports')
const { ElementWithMappedObject } = require('./../async-dom/exports')

class E_JSON_TEMPLATE extends E {
constructor (node) {
super(node)
}

activate () {
new ShownElement(
new FirstParsedElmSelector(
this.node.getAttribute('data-ajax-icon')
).as('AJAX_ICON')
).after(
new PreparedProgressBar(
new FirstParsedElmSelector(
this.node.getAttribute('data-progress-bar')
)
).as('PROGRESS_BAR').after(
new ResponseFromAjaxRequest(
new CreatedOptions(
'url', this.node.getAttribute('data-src'),
'method', 'GET',
'headers', new ParsedJSON(
this.node.getAttribute('data-request-headers') || '{}'
),
'progressEvent', new ShowProgressEvent(
as('PROGRESS_BAR')
)
)
).as('RESPONSE').after(
new HiddenElement(
as('AJAX_ICON')
).after(
new ElementWithMappedObject(
this.node,
new JSResponseByHTTPReponseComponents(
new ParsedJSON(
new StringFromBuffer(
new ResponseBody(
as('RESPONSE')
)
)
),
new ResponseHeaders(
as('RESPONSE')
),
new ResponseStatusCode(
as('RESPONSE')
)
)
)
)
)
)
).call()
}
}

module.exports = E_JSON_TEMPLATE
1 change: 1 addition & 0 deletions src/E/exports.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
'e-html': require('./E_HTML'),
'e-json': require('./E_JSON'),
'e-json-template': require('./E_JSON_TEMPLATE'),
'e-if': require('./E_IF'),
'e-for-each': require('./E_FOR_EACH'),
'e-form': require('./E_FORM'),
Expand Down
14 changes: 10 additions & 4 deletions src/MutationObservation.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,26 @@ class MutationObservation {
}

nodeName (node) {
if (this.isTemplateWithType(node, 'e-page-with-url')) {
if (this.isTemplateWithType(node, 'e-json')) {
return 'e-json-template'
} else if (this.isTemplateWithTypeExclusively(node, 'e-page-with-url')) {
return 'e-page-with-url'
} else if (this.isTemplateWithType(node, 'e-if')) {
} else if (this.isTemplateWithTypeExclusively(node, 'e-if')) {
return 'e-if'
} else if (this.isTemplateWithType(node, 'e-for-each')) {
} else if (this.isTemplateWithTypeExclusively(node, 'e-for-each')) {
return 'e-for-each'
}
return node.nodeName.toLowerCase()
}

isTemplateWithType (node, type) {
isTemplateWithTypeExclusively (node, type) {
if (node.nodeName.toLowerCase() === type) {
throw new Error(`${type} must be <template>`)
}
return this.isTemplateWithType(node, type)
}

isTemplateWithType (node, type) {
if (this.isTemplate(node)) {
const templateType = node.getAttribute('is')
if (templateType) {
Expand Down

0 comments on commit 5fb5a93

Please sign in to comment.