mirror of
https://github.com/Oreolek/raconteur.git
synced 2024-07-16 21:34:24 +03:00
144 lines
3.9 KiB
JavaScript
144 lines
3.9 KiB
JavaScript
/* Element Helpers */
|
|
/*
|
|
While you can write HTML elements by hand, those helpers make it easier to
|
|
place anchors (especially with special purpose) and spans.
|
|
|
|
They define a monadic interface:
|
|
|
|
a.id('my-link').content('link').writer('my-ref')
|
|
-> <a id="my-link" href="./_writer_my-ref">link</a>
|
|
|
|
span -> <span></span>
|
|
|
|
The object supplies a toString() method that outputs the tag. Element
|
|
helpers are immutable, so theoretically this should be safe from side
|
|
effects. This interface allows the safe definition of templates which
|
|
can be used and modified at will, for instance:
|
|
|
|
let mySpanClass = span.class('myclass'); // -> <span class="myclass"></span>
|
|
mySpanClass.content("Hello!"); // -> <span class="myclass">Hello!</span>
|
|
|
|
Methods on an elementHelper return a new elementHelper that inherits from
|
|
itself. Since those objects (should be) immutable by being frozen when they
|
|
are created, this is semantically equivalent to returning a copy but more
|
|
efficient in terms
|
|
|
|
Methods:
|
|
class :: String -> elementHelper
|
|
Returns a new elementHelper with the given class added.
|
|
|
|
classes :: [String] -> elementHelper
|
|
Returns a new elementHelper with the given classes.
|
|
|
|
id :: String -> elementHelper
|
|
Returns a new elementHelper with the given id.
|
|
|
|
|
|
*/
|
|
|
|
var md = require('markdown-it');
|
|
|
|
var markdown = new md({
|
|
typographer: true,
|
|
html: true
|
|
});
|
|
|
|
var elementHelper = function (element) {
|
|
this.element = element;
|
|
this._classes = [];
|
|
};
|
|
|
|
var elementSetterGen = function (prop) {
|
|
return function (value) {
|
|
return Object.freeze(Object.create(this, {
|
|
[prop]: {value}
|
|
}));
|
|
};
|
|
};
|
|
|
|
elementHelper.prototype.classes = function (newClasses) {
|
|
return Object.freeze(Object.create(this, {
|
|
_classes: {
|
|
value: newClasses
|
|
}
|
|
}));
|
|
};
|
|
|
|
elementHelper.prototype.class = function (newClass) {
|
|
return this.classes(this._classes.concat(newClass));
|
|
};
|
|
|
|
elementHelper.prototype.id = elementSetterGen("_id");
|
|
elementHelper.prototype.type = elementSetterGen("_linkType");
|
|
elementHelper.prototype.content = elementSetterGen("_content");
|
|
elementHelper.prototype.ref = elementSetterGen("_ref");
|
|
elementHelper.prototype.url = elementHelper.prototype.ref;
|
|
elementHelper.prototype.situation = elementHelper.prototype.ref;
|
|
elementHelper.prototype.once = () => this.class('once');
|
|
|
|
var linkTypeGen = function (type) {
|
|
return function (ref) {
|
|
return this.type(type).ref(ref);
|
|
}
|
|
};
|
|
|
|
elementHelper.prototype.writer = linkTypeGen("writer");
|
|
elementHelper.prototype.replacer = linkTypeGen("replacer");
|
|
elementHelper.prototype.inserter = linkTypeGen("inserter");
|
|
elementHelper.prototype.action = linkTypeGen("action");
|
|
|
|
elementHelper.prototype.toString = function () {
|
|
var classes = "",
|
|
classString = "",
|
|
idString = "",
|
|
hrefString= "",
|
|
contentString = "";
|
|
|
|
if (this._classes) {
|
|
classes += this._classes.join(' ');
|
|
}
|
|
if (this._linkType) {
|
|
classes += (' ' + this._linkType);
|
|
}
|
|
if (classes) {
|
|
classString = ` class="${classes}"`;
|
|
}
|
|
|
|
if (this._id) {
|
|
idString = ` id="${this._id}"`;
|
|
}
|
|
|
|
if (this.element === "a") {
|
|
if (this._linkType) {
|
|
if (this._linkType === "action") {
|
|
hrefString = ` href="./${this._ref}"`;
|
|
} else {
|
|
hrefString = ` href="./_${this._linkType}_${this._ref}"`;
|
|
}
|
|
} else {
|
|
hrefString = ` href="${this._ref}"`;
|
|
}
|
|
}
|
|
|
|
if (this._content) {
|
|
contentString = markdown.renderInline(this._content);
|
|
}
|
|
|
|
return `<${this.element}${classString}${idString}${hrefString}>${contentString}</${this.element}>`;
|
|
};
|
|
|
|
var a_proto = Object.freeze(new elementHelper("a"));
|
|
var span_proto = Object.freeze(new elementHelper("span"));
|
|
|
|
var a = function (content) {
|
|
if (content) return a_proto.content(content);
|
|
return a_proto;
|
|
};
|
|
|
|
var span = function (content) {
|
|
if (content) return span_proto.content(content);
|
|
return span_proto;
|
|
};
|
|
|
|
module.exports.a = a;
|
|
module.exports.span = span; |