sclass HTMLFramer1 {
S title;
bool titleIsHTML;
new L navItems;
new L contents; // items will be evaluated to strings upon rendering
new LinkedHashSet headElements; // automatically avoid duplication
bool navBeforeTitle;
new L willRender;
srecord NavItem(S link, S html) {
bool targetBlank;
}
public S get() { ret render(); }
swappable S render() {
callFAll(willRender);
ret hhtml(hhead(htitle(titleIsHTML ? hTitleClean(title) : title)
+ lines(headElements))
+ hbody(
(navBeforeTitle ? renderNav() + renderTitle()
: renderTitle() + renderNav())
+ nemptyLines(contents)));
}
swappable S renderTitle() {
ret h1(encodedTitle());
}
S encodedTitle() {
//printVars_str encodedTitle(+title, +titleIsHTML);
ret titleIsHTML ? title : htmlEncode2(title);
}
swappable S renderNav() {
if (empty(navItems)) ret "";
ret div_vbar(map renderNavItem(navItems), style := "margin-bottom: 0.5em");
}
S renderNavItem(NavItem ni) {
ret ahref_possiblyTargetBlank(ni.link, ni.html, ni.targetBlank);
}
void addNavItem(S html) {
navItems.add(new NavItem(null, html));
}
void addNavItems(Iterable htmls) {
forEach addNavItem(htmls);
}
void addNavItem(S link, S html, O... _) {
navItems.add(setAll(new NavItem(link, html), filterParams(_, 'targetBlank)));
}
void addInHead aka addInHEAD(O html) {
headElements.add(str(html));
}
// legacy signature for binary compatibility
void add(S html) { add((O) html); }
// convenience signature for lambdas
void add(IF0 html) { add(lambdaToToString(html)); }
// add contents: TODO move things to head automatically
void add(O html) {
if (notNullOrEmptyString(html))
contents.add(html);
}
void addAll(Cl l) { forEach add(l); }
void clearNavItems {
navItems.clear();
}
selfType setTitle(S title) {
this.title = title;
this;
}
S htmlTitle(S title) {
this.title = title;
titleIsHTML = true;
ret title;
}
Cl headElements() { ret headElements; }
}